Skip to content

⬆️ Upgrade dependency jwt to v2.10.3 [SECURITY]#1384

Merged
renovate[bot] merged 1 commit into
mainfrom
renovate/rubygems-jwt-vulnerability
Jun 3, 2026
Merged

⬆️ Upgrade dependency jwt to v2.10.3 [SECURITY]#1384
renovate[bot] merged 1 commit into
mainfrom
renovate/rubygems-jwt-vulnerability

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate Bot commented May 18, 2026

This PR contains the following updates:

Package Change Age Confidence
jwt (changelog) 2.10.22.10.3 age confidence

ruby-jwt: Empty-key HMAC bypass; cross-language sibling of CVE-2026-44351

CVE-2026-45363 / GHSA-c32j-vqhx-rx3x

More information

Details

JWT.decode(token, '', true, algorithm: 'HS256') accepts an attacker-forged token.
OpenSSL::HMAC.digest('SHA256', '', payload) returns a valid digest under an empty key, and no raise InvalidKeyError if key.empty? precondition exists in the HMAC algorithm.

JWT.decode(token, "", true, algorithm: 'HS256')
  -> JWA::Hmac.verify(verification_key: "", ...)
  -> OpenSSL::HMAC.digest('SHA256', "", signing_input) == signature

The same path is reached when a keyfinder block or key_finder: argument returns "", nil, or an
array containing nil for an unknown key. JWT::Decode#find_key only rejects literal nil and empty
arrays, and JWT::JWA::Hmac silently coerces nil to "" (signing_key ||= '') before signing.

JWT.decode(token, nil, true, algorithms: ['HS256']) { |_h| "" }
  -> find_key returns ""               # "" && !Array("").empty? == true
  -> JWA::Hmac.verify(verification_key: "", ...)
  -> verifies

Common application patterns that produce the unsafe value: redis.get("kid:#{kid}").to_s, ORM string columns with default: '', ENV['SECRET'] || '', Hash.new('') lookups, [primary, fallback] where fallback may be nil. Applications passing a non-empty static key:, or whose keyfinder returns nil / raises on miss, are not affected.

The existing enforce_hmac_key_length option would block this but defaults to false. On OpenSSL ≥ 3.5 the empty-key HMAC.digest call no longer raises, so the OpenSSL-3.0 rescue in JWA::Hmac#sign does not fire.

Affects HS256/HS384/HS512 via both JWT.decode (positional key and block keyfinder) and
JWT::EncodedToken#verify_signature!(key_finder:)

Severity

  • CVSS Score: 7.4 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


ruby-jwt: Empty-key HMAC bypass; cross-language sibling of CVE-2026-44351

CVE-2026-45363 / GHSA-c32j-vqhx-rx3x

More information

Details

JWT.decode(token, '', true, algorithm: 'HS256') accepts an attacker-forged token.
OpenSSL::HMAC.digest('SHA256', '', payload) returns a valid digest under an empty key, and no raise InvalidKeyError if key.empty? precondition exists in the HMAC algorithm.

JWT.decode(token, "", true, algorithm: 'HS256')
  -> JWA::Hmac.verify(verification_key: "", ...)
  -> OpenSSL::HMAC.digest('SHA256', "", signing_input) == signature

The same path is reached when a keyfinder block or key_finder: argument returns "", nil, or an
array containing nil for an unknown key. JWT::Decode#find_key only rejects literal nil and empty
arrays, and JWT::JWA::Hmac silently coerces nil to "" (signing_key ||= '') before signing.

JWT.decode(token, nil, true, algorithms: ['HS256']) { |_h| "" }
  -> find_key returns ""               # "" && !Array("").empty? == true
  -> JWA::Hmac.verify(verification_key: "", ...)
  -> verifies

Common application patterns that produce the unsafe value: redis.get("kid:#{kid}").to_s, ORM string columns with default: '', ENV['SECRET'] || '', Hash.new('') lookups, [primary, fallback] where fallback may be nil. Applications passing a non-empty static key:, or whose keyfinder returns nil / raises on miss, are not affected.

The existing enforce_hmac_key_length option would block this but defaults to false. On OpenSSL ≥ 3.5 the empty-key HMAC.digest call no longer raises, so the OpenSSL-3.0 rescue in JWA::Hmac#sign does not fire.

Affects HS256/HS384/HS512 via both JWT.decode (positional key and block keyfinder) and
JWT::EncodedToken#verify_signature!(key_finder:)

Severity

  • CVSS Score: 7.4 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


Release Notes

jwt/ruby-jwt (jwt)

v2.10.3: jwt-2.10.3

Compare Source

v2.10.3 (2026-05-22)

Full Changelog

Fixes and enhancements:


Configuration

📅 Schedule: (in timezone Europe/Paris)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot force-pushed the renovate/rubygems-jwt-vulnerability branch from 7473e61 to f996066 Compare June 3, 2026 03:41
@renovate renovate Bot added this pull request to the merge queue Jun 3, 2026
@renovate renovate Bot changed the title ⬆️ Upgrade dependency jwt to v3 [SECURITY] ⬆️ Upgrade dependency jwt to v2.10.3 [SECURITY] Jun 3, 2026
Merged via the queue into main with commit b937c72 Jun 3, 2026
@renovate renovate Bot deleted the renovate/rubygems-jwt-vulnerability branch June 3, 2026 03:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants