-
-
Notifications
You must be signed in to change notification settings - Fork 233
GHSA SYNC: 1 brand new jwt advisory #1057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| --- | ||
| gem: jwt | ||
| cve: 2026-45363 | ||
| ghsa: c32j-vqhx-rx3x | ||
| url: https://www.cve.org/CVERecord?id=CVE-2026-45363 | ||
| title: 'ruby-jwt: Empty-key HMAC bypass; cross-language sibling of CVE-2026-44351' | ||
| date: 2026-05-18 | ||
| description: | | ||
| `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:)`. | ||
| cvss_v3: 7.4 | ||
| patched_versions: | ||
| - "~> 2.10.3" | ||
| - ">= 3.2.0" | ||
| related: | ||
| url: | ||
| - https://github.com/jwt/ruby-jwt/security/advisories/GHSA-c32j-vqhx-rx3x | ||
| - https://github.com/jwt/ruby-jwt/commit/db560b769a07bd9724e77ff505011ac01872106f | ||
| - https://github.com/jwt/ruby-jwt/releases/tag/v3.2.0 | ||
| - https://github.com/advisories/GHSA-c32j-vqhx-rx3x | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it worth to keep this url also? It is almost the same page as the main url.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there really any value in keeping both links?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also collect URLs and put them in the related: / url: field then pick an advisory URL to use in the url: field.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the CVE link to the main URL field. Let me know if you need any other changes |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK to remove the duplicate @jasnow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what duplicate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems none, it is in root url and here also which is intended 💪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused. Think I need more words to describe the original feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is ok to just ignore it. I wasn't sure if root url and related urls can overlap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've kept the related URLs that originated from the GHSA sync.