VYPR
Moderate severityNVD Advisory· Published Dec 25, 2023· Updated Aug 2, 2024

CVE-2023-50658

CVE-2023-50658

Description

The jose2go component before 1.6.0 for Go allows attackers to cause a denial of service (CPU consumption) via a large p2c (aka PBES2 Count) value.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

The jose2go Go library before v1.6.0 lacks validation on PBES2 iteration counts, enabling CPU exhaustion denial of service via a crafted p2c value.

Vulnerability

The jose2go library for Go, prior to version 1.6.0, contains a denial-of-service vulnerability in its PBES2-HMAC-AESKW algorithm implementation. The library fails to impose an upper bound on the p2c (PBES2 Count) parameter, which represents the number of iterations used in key derivation. An attacker can supply an arbitrarily large iteration count, causing excessive CPU consumption during decryption [1][3].

Exploitation

An attacker can exploit this vulnerability by crafting a JSON Web Token (JWT) with a p2c header set to a very high integer value. When the recipient attempts to decrypt or verify the token using jose2go before v1.6.0, the library performs the specified number of PBES2 iterations without validation, leading to prolonged computation and CPU exhaustion [3]. No prior authentication is required; the attacker only needs to deliver the malicious JWT to a vulnerable system.

Impact

Successful exploitation results in a denial of service due to high CPU consumption, potentially rendering the affected application unresponsive. This vulnerability does not enable data leakage or privilege escalation; it is purely a resource exhaustion issue [1][3].

Mitigation

The vulnerability is fixed in jose2go version 1.6.0, which introduces maximum iteration count limits (maxIterations) for the PBES2 algorithm [4]. All users should upgrade to v1.6.0 or later. There are no known workarounds [1][3].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/dvsekhvalnov/jose2goGo
< 1.6.01.6.0

Affected products

40

Patches

1
a4584e9dd712

Adding min/max iteration count guards to pbes2-hmac-aeskw algorithm

2 files changed · +79 6
  • jose_test.go+34 0 modified
    @@ -1634,6 +1634,40 @@ func (s *TestSuite) TestDecrypt_PBSE2_HS512_A256KW_A256CBC_HS512(c *C) {
     	c.Assert(test, Equals, `{"exp":1392553211,"sub":"alice","nbf":1392552611,"aud":["https:\/\/app-one.com","https:\/\/app-two.com"],"iss":"https:\/\/openid.net","jti":"586dd129-a29f-49c8-9de7-454af1155e27","iat":1392552611}`)
     }
     
    +func (s *TestSuite) TestDecrypt_PBSE2_HS512_A256KW_A256CBC_HS512_MinIterationViolation(c *C) {
    +	//given
    +	pbes2Hs512 := DeregisterJwa(PBES2_HS512_A256KW)
    +	RegisterJwa(NewPbse2HmacAesKWAlg(256, 300000, 10000))
    +	token := "eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwicDJjIjo4MTkyLCJwMnMiOiJCUlkxQ1M3VXNpaTZJNzhkIn0.ovjAL7yRnB_XdJbK8lAaUDRZ-CyVeio8f4pnqOt1FPj1PoQAdEX3S5x6DlzR8aqN_WR5LUwdqDSyUDYhSurnmq8VLfzd3AEe.YAjH6g_zekXJIlPN4Ooo5Q.tutaltxpeVyayXZ9pQovGXTWTf_GWWvtu25Jeg9jgoH0sUX9KCnL00A69e4GJR6EMxalmWsa45AItffbwjUBmwdyklC4ZbTgaovVRs-UwqsZFBO2fpEb7qLajjwra7o4OegzgXDD0jhrKrUusvRWGBvenvumb5euibUxmIfBUcVF1JbdfYxx7ztFeS-QKJpDkE00zyEkViq-QxfrMVl5p7LGmTz8hMrFL3LXLokypZSDgFBfsUzChJf3mlYzxiGaGUqhs7NksQJDoUYf6prPow.XwRVfVTTPogO74RnxZD_9Mse26fTSehna1pbWy4VHfY"
    +
    +	//when
    +	test, headers, err := Decode(token, "top secret")
    +	fmt.Printf("\np2c min iteration err= %v\n", err)
    +
    +	//then
    +	RegisterJwa(pbes2Hs512)
    +	c.Assert(err, NotNil)
    +	c.Assert(test, Equals, "")
    +	c.Assert(headers, IsNil)
    +}
    +
    +func (s *TestSuite) TestDecrypt_PBSE2_HS512_A256KW_A256CBC_HS512_MaxIterationViolation(c *C) {
    +	//given
    +	pbes2Hs512 := DeregisterJwa(PBES2_HS512_A256KW)
    +	RegisterJwa(NewPbse2HmacAesKWAlg(256, 8000, 0))
    +	token := "eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwicDJjIjo4MTkyLCJwMnMiOiJCUlkxQ1M3VXNpaTZJNzhkIn0.ovjAL7yRnB_XdJbK8lAaUDRZ-CyVeio8f4pnqOt1FPj1PoQAdEX3S5x6DlzR8aqN_WR5LUwdqDSyUDYhSurnmq8VLfzd3AEe.YAjH6g_zekXJIlPN4Ooo5Q.tutaltxpeVyayXZ9pQovGXTWTf_GWWvtu25Jeg9jgoH0sUX9KCnL00A69e4GJR6EMxalmWsa45AItffbwjUBmwdyklC4ZbTgaovVRs-UwqsZFBO2fpEb7qLajjwra7o4OegzgXDD0jhrKrUusvRWGBvenvumb5euibUxmIfBUcVF1JbdfYxx7ztFeS-QKJpDkE00zyEkViq-QxfrMVl5p7LGmTz8hMrFL3LXLokypZSDgFBfsUzChJf3mlYzxiGaGUqhs7NksQJDoUYf6prPow.XwRVfVTTPogO74RnxZD_9Mse26fTSehna1pbWy4VHfY"
    +
    +	//when
    +	test, headers, err := Decode(token, "top secret")
    +	fmt.Printf("\np2c max iteration err= %v\n", err)
    +
    +	//then
    +	RegisterJwa(pbes2Hs512)
    +	c.Assert(err, NotNil)
    +	c.Assert(test, Equals, "")
    +	c.Assert(headers, IsNil)
    +}
    +
     func (s *TestSuite) TestEncrypt_PBSE2_HS256_A128KW_A128GCM(c *C) {
     	//given
     	payload := `{"hello": "world"}`
    
  • pbse2_hmac_aeskw.go+45 6 modified
    @@ -4,6 +4,7 @@ import (
     	"crypto/sha256"
     	"crypto/sha512"
     	"errors"
    +	"fmt"
     	"hash"
     
     	"github.com/dvsekhvalnov/jose2go/arrays"
    @@ -12,15 +13,28 @@ import (
     )
     
     func init() {
    -	RegisterJwa(&Pbse2HmacAesKW{keySizeBits: 128, aesKW: &AesKW{keySizeBits: 128}})
    -	RegisterJwa(&Pbse2HmacAesKW{keySizeBits: 192, aesKW: &AesKW{keySizeBits: 192}})
    -	RegisterJwa(&Pbse2HmacAesKW{keySizeBits: 256, aesKW: &AesKW{keySizeBits: 256}})
    +	RegisterJwa(NewPbse2HmacAesKWAlg(128, 310000, 0))
    +	RegisterJwa(NewPbse2HmacAesKWAlg(192, 250000, 0))
    +	RegisterJwa(NewPbse2HmacAesKWAlg(256, 120000, 0))
     }
     
     // PBSE2 with HMAC key management algorithm implementation
     type Pbse2HmacAesKW struct {
    -	keySizeBits int
    -	aesKW       JwaAlgorithm
    +	keySizeBits   int
    +	aesKW         JwaAlgorithm
    +	maxIterations int64
    +	minIterations int64
    +}
    +
    +func NewPbse2HmacAesKWAlg(keySize int, maxIters int64, minIters int64) JwaAlgorithm {
    +	switch keySize {
    +	case 128:
    +		return &Pbse2HmacAesKW{keySizeBits: 128, maxIterations: maxIters, minIterations: minIters, aesKW: &AesKW{keySizeBits: 128}}
    +	case 192:
    +		return &Pbse2HmacAesKW{keySizeBits: 192, maxIterations: maxIters, minIterations: minIters, aesKW: &AesKW{keySizeBits: 192}}
    +	default:
    +		return &Pbse2HmacAesKW{keySizeBits: 256, maxIterations: maxIters, minIterations: minIters, aesKW: &AesKW{keySizeBits: 256}}
    +	}
     }
     
     func (alg *Pbse2HmacAesKW) Name() string {
    @@ -46,6 +60,21 @@ func (alg *Pbse2HmacAesKW) WrapNewKey(cekSizeBits int, key interface{}, header m
     			return nil, nil, err
     		}
     
    +		// use user provided iteration counts if any
    +		if p2c, ok := header["p2c"].(int); ok {
    +			iterationCount = p2c
    +		}
    +
    +		if int64(iterationCount) > alg.maxIterations {
    +			return nil, nil, errors.New(
    +				fmt.Sprintf("Pbse2HmacAesKW.Unwrap(): expected 'p2c' to be less than %v but got %v", alg.maxIterations, iterationCount))
    +		}
    +
    +		if int64(iterationCount) < alg.minIterations {
    +			return nil, nil, errors.New(
    +				fmt.Sprintf("Pbse2HmacAesKW.Unwrap(): expected 'p2c' to be higher than %v but got %v", alg.minIterations, iterationCount))
    +		}
    +
     		header["p2c"] = iterationCount
     		header["p2s"] = base64url.Encode(saltInput)
     
    @@ -69,8 +98,18 @@ func (alg *Pbse2HmacAesKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeB
     			return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2c' param in JWT header, but was not found.")
     		}
     
    +		if int64(p2c) > alg.maxIterations {
    +			return nil, errors.New(
    +				fmt.Sprintf("Pbse2HmacAesKW.Unwrap(): expected 'p2c' to be less than %v but got %v", alg.maxIterations, p2c))
    +		}
    +
    +		if int64(p2c) < alg.minIterations {
    +			return nil, errors.New(
    +				fmt.Sprintf("Pbse2HmacAesKW.Unwrap(): expected 'p2c' to be higher than %v but got %v", alg.minIterations, p2c))
    +		}
    +
     		if p2s, ok = header["p2s"].(string); !ok {
    -			return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2s' param in JWT header, but was not found.")
    +			return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2s' param in JWT header, but was not found")
     		}
     
     		var saltInput []byte
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.