Skip to content

Commit 649b222

Browse files
wladsRubySec CI
authored andcommitted
Updated advisory posts against rubysec/ruby-advisory-db@9d9d98f
1 parent a8ba155 commit 649b222

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
layout: advisory
3+
title: 'CVE-2026-45363 (jwt): ruby-jwt: Empty-key HMAC bypass; cross-language sibling
4+
of CVE-2026-44351'
5+
comments: false
6+
categories:
7+
- jwt
8+
advisory:
9+
gem: jwt
10+
cve: 2026-45363
11+
ghsa: c32j-vqhx-rx3x
12+
url: https://www.cve.org/CVERecord?id=CVE-2026-45363
13+
title: 'ruby-jwt: Empty-key HMAC bypass; cross-language sibling of CVE-2026-44351'
14+
date: 2026-05-18
15+
description: |-
16+
`JWT.decode(token, '', true, algorithm: 'HS256')` accepts an
17+
attacker-forged token. `OpenSSL::HMAC.digest('SHA256', '', payload)`
18+
returns a valid digest under an empty key, and no
19+
`raise InvalidKeyError if key.empty?` precondition exists in the HMAC
20+
algorithm.
21+
22+
```
23+
JWT.decode(token, "", true, algorithm: 'HS256')
24+
-> JWA::Hmac.verify(verification_key: "", ...)
25+
-> OpenSSL::HMAC.digest('SHA256', "", signing_input) == signature
26+
```
27+
28+
The same path is reached when a keyfinder block or key_finder: argument
29+
returns "", nil, or an array containing nil for an unknown key.
30+
JWT::Decode#find_key only rejects literal nil and empty arrays, and
31+
JWT::JWA::Hmac silently coerces nil to "" (signing_key ||= '') before
32+
signing.
33+
34+
```
35+
JWT.decode(token, nil, true, algorithms: ['HS256']) { |_h| "" }
36+
-> find_key returns "" # "" && !Array("").empty? == true
37+
-> JWA::Hmac.verify(verification_key: "", ...)
38+
-> verifies
39+
```
40+
41+
Common application patterns that produce the unsafe value:
42+
`redis.get("kid:#{kid}").to_s`, ORM string columns with `default: ''`,
43+
`ENV['SECRET'] || ''`, `Hash.new('')` lookups, `[primary, fallback]`
44+
where fallback may be nil. Applications passing a non-empty static
45+
`key:`, or whose keyfinder returns nil / raises on miss, are not
46+
affected.
47+
48+
The existing `enforce_hmac_key_length` option would block this but
49+
defaults to false. On OpenSSL ≥ 3.5 the empty-key HMAC.digest call no
50+
longer raises, so the OpenSSL-3.0 rescue in JWA::Hmac#sign does not
51+
fire.
52+
53+
Affects HS256/HS384/HS512 via both JWT.decode (positional key and block
54+
keyfinder) and `JWT::EncodedToken#verify_signature!(key_finder:)`.
55+
cvss_v3: 7.4
56+
patched_versions:
57+
- "~> 2.10.3"
58+
- ">= 3.2.0"
59+
related:
60+
url:
61+
- https://github.com/jwt/ruby-jwt/security/advisories/GHSA-c32j-vqhx-rx3x
62+
- https://github.com/jwt/ruby-jwt/commit/db560b769a07bd9724e77ff505011ac01872106f
63+
- https://github.com/jwt/ruby-jwt/releases/tag/v3.2.0
64+
- https://github.com/advisories/GHSA-c32j-vqhx-rx3x
65+
---

0 commit comments

Comments
 (0)