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.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/dvsekhvalnov/jose2goGo | < 1.6.0 | 1.6.0 |
Affected products
40- jose2go/jose2godescription
- osv-coords39 versionspkg:apk/chainguard/jitsucom-bulkerpkg:apk/chainguard/jitsucom-bulker-bulkerpkg:apk/chainguard/jitsucom-bulker-bulker-compatpkg:apk/chainguard/jitsucom-bulker-ingestpkg:apk/chainguard/jitsucom-bulker-ingest-compatpkg:apk/chainguard/jitsucom-bulker-ingmgrpkg:apk/chainguard/jitsucom-bulker-ingmgr-compatpkg:apk/chainguard/jitsucom-bulker-sidecarpkg:apk/chainguard/jitsucom-bulker-sidecar-compatpkg:apk/chainguard/jitsucom-bulker-syncctlpkg:apk/chainguard/jitsucom-bulker-syncctl-compatpkg:apk/chainguard/telegraf-1.26pkg:apk/chainguard/telegraf-1.27pkg:apk/chainguard/telegraf-1.28pkg:apk/chainguard/telegraf-1.29pkg:apk/chainguard/vault-1.13pkg:apk/chainguard/vault-1.13-compatpkg:apk/chainguard/vault-1.13-entrypointpkg:apk/chainguard/vault-fips-1.14pkg:apk/chainguard/vault-fips-1.14-compatpkg:apk/wolfi/jitsucom-bulkerpkg:apk/wolfi/jitsucom-bulker-bulkerpkg:apk/wolfi/jitsucom-bulker-bulker-compatpkg:apk/wolfi/jitsucom-bulker-ingestpkg:apk/wolfi/jitsucom-bulker-ingest-compatpkg:apk/wolfi/jitsucom-bulker-ingmgrpkg:apk/wolfi/jitsucom-bulker-ingmgr-compatpkg:apk/wolfi/jitsucom-bulker-sidecarpkg:apk/wolfi/jitsucom-bulker-sidecar-compatpkg:apk/wolfi/jitsucom-bulker-syncctlpkg:apk/wolfi/jitsucom-bulker-syncctl-compatpkg:apk/wolfi/telegraf-1.26pkg:apk/wolfi/telegraf-1.27pkg:apk/wolfi/telegraf-1.28pkg:apk/wolfi/telegraf-1.29pkg:apk/wolfi/vault-1.13pkg:apk/wolfi/vault-1.13-compatpkg:apk/wolfi/vault-1.13-entrypointpkg:golang/github.com/dvsekhvalnov/jose2go
< 2.6.0-r2+ 38 more
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 1.26.3-r11
- (no CPE)range: < 1.27.4-r11
- (no CPE)range: < 1.28.5-r4
- (no CPE)range: < 1.29.1-r1
- (no CPE)range: < 1.13.12-r1
- (no CPE)range: < 1.13.12-r1
- (no CPE)range: < 1.13.12-r1
- (no CPE)range: < 1.14.10-r0
- (no CPE)range: < 1.14.10-r0
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 2.6.0-r2
- (no CPE)range: < 1.26.3-r11
- (no CPE)range: < 1.27.4-r11
- (no CPE)range: < 1.28.5-r4
- (no CPE)range: < 1.29.1-r1
- (no CPE)range: < 1.13.12-r1
- (no CPE)range: < 1.13.12-r1
- (no CPE)range: < 1.13.12-r1
- (no CPE)range: < 1.6.0
Patches
1a4584e9dd712Adding 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- github.com/advisories/GHSA-6294-6rgp-fr7rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-50658ghsaADVISORY
- github.com/dvsekhvalnov/jose2go/commit/a4584e9dd7128608fedbc67892eba9697f0d5317ghsaWEB
- github.com/dvsekhvalnov/jose2go/compare/v1.5.0...v1.6.0ghsaWEB
- github.com/dvsekhvalnov/jose2go/issues/31ghsaWEB
- pkg.go.dev/vuln/GO-2023-2409ghsaWEB
- www.blackhat.com/us-23/briefings/schedule/ghsaWEB
News mentions
0No linked articles in our index yet.