Skip to content

Commit

Permalink
Fix decryption DoS: Reject too high p2c (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsha committed Nov 8, 2023
1 parent 260aa26 commit 65351c2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,8 @@
# v3.0.1

Fixed:
- Security issue: an attacker specifying a large "p2c" value can cause
JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
disclosure and to Tom Tervoort for originally publishing the category of attack.
https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
39 changes: 39 additions & 0 deletions crypter_test.go
Expand Up @@ -610,6 +610,45 @@ func TestEncrypterWithPBES2(t *testing.T) {
}
}

func TestRejectTooHighP2C(t *testing.T) {
expected := []byte("Lorem ipsum dolor sit amet")
algs := []KeyAlgorithm{
PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW,
}

// Check with both strings and []byte
recipientKeys := []interface{}{"password", []byte("password")}
for _, key := range recipientKeys {
for _, alg := range algs {
enc, err := NewEncrypter(A128GCM, Recipient{Algorithm: alg, PBES2Count: 1000001, Key: &JSONWebKey{
KeyID: "test-id",
Key: key,
}}, nil)
if err != nil {
t.Error(err)
}

ciphertext, _ := enc.Encrypt(expected)

serialized1, _ := ciphertext.CompactSerialize()
serialized2 := ciphertext.FullSerialize()

parsed1, _ := ParseEncrypted(serialized1)
parsed2, _ := ParseEncrypted(serialized2)

_, err = parsed1.Decrypt("password")
if err == nil {
t.Fatal("expected error decrypting expensive PBES2 key, got none")
}

_, err = parsed2.Decrypt([]byte("password"))
if err == nil {
t.Fatal("expected error decrypting expensive PBES2 key, got none")
}
}
}
}

type testKey struct {
enc, dec interface{}
}
Expand Down
5 changes: 5 additions & 0 deletions symmetric.go
Expand Up @@ -420,6 +420,11 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
if p2c <= 0 {
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer")
}
if p2c > 1000000 {
// An unauthenticated attacker can set a high P2C value. Set an upper limit to avoid
// DoS attacks.
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: too high")
}

// salt is UTF8(Alg) || 0x00 || Salt Input
alg := headers.getAlgorithm()
Expand Down

0 comments on commit 65351c2

Please sign in to comment.