ruby-jwt CVE-2026-45363
CRITICALSeverity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Primary rating from Vendor (https://github.com/jwt/ruby-jwt) · only source for this CVE.
CVSS VectorVendor: https://github.com/jwt/ruby-jwt
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Lifecycle Timeline
5DescriptionCVE.org
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) == signatureThe 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: "", ...)
-> verifiesCommon 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:)
AnalysisAI
Authentication bypass in the ruby-jwt gem (versions < 3.2.0) allows remote attackers to forge valid HS256/HS384/HS512 tokens when an application supplies an empty string or nil as the verification key. Because OpenSSL::HMAC.digest happily computes a digest under an empty key and JWT::JWA::Hmac coerces nil to '' without validating, any application whose key lookup degrades to '' (common with Redis misses, ORM string defaults, or ENV['SECRET'] || '' patterns) will accept attacker-signed tokens. No public exploit identified at time of analysis, but the vendor advisory (GHSA-c32j-vqhx-rx3x) and the v3.2.0 patch confirm the issue and the trivial forgery primitive.
Technical ContextAI
ruby-jwt is the canonical Ruby implementation of RFC 7519 JSON Web Tokens, widely used by Rails and Sinatra applications for session and API authentication. The root cause maps to CWE-287 (Improper Authentication): JWT::JWA::Hmac#verify accepted an empty verification key, and signing_key ||= '' silently substituted '' for nil before delegating to OpenSSL::HMAC.digest. On OpenSSL 3.0 the underlying call previously raised an EVP_PKEY_new_mac_key malloc failure, which the library caught and converted to a decode error - an accidental defense - but on OpenSSL ≥ 3.5 that call no longer raises, removing the implicit guard. JWT::Decode#find_key further compounded the issue by rejecting only literal nil and empty arrays, so a keyfinder block returning '' was treated as a valid key. The CPE pkg:rubygems/jwt identifies the affected package, and the fix introduces an ensure_valid_key! helper that rejects non-String and empty keys before any HMAC computation.
RemediationAI
Upgrade the jwt gem to the vendor-released patch version 3.2.0 or later (gem 'jwt', '>= 3.2.0' in the Gemfile, then bundle update jwt); the fix is commit db560b769a07bd9724e77ff505011ac01872106f, which adds an ensure_valid_key! check that rejects non-String and empty keys before any HMAC computation. Until the upgrade can be deployed, enable the existing enforce_hmac_key_length option (off by default) which rejects short keys including '', though this changes behavior for any code that legitimately relied on short keys for testing. Audit all JWT.decode and EncodedToken#verify_signature! call sites to ensure the key source cannot degrade to '' or nil - fix patterns such as redis.get(...).to_s, ENV['SECRET'] || '', ORM string columns with default: '', Hash.new('') lookups, and [primary, fallback]-with-nil arrays by raising on missing keys instead of substituting an empty string. See the GHSA advisory at https://github.com/jwt/ruby-jwt/security/advisories/GHSA-c32j-vqhx-rx3x for full details.
LiteSpeed User-End cPanel Plugin before 2.4.5 allows privilege escalation (possibly to root), as exploited in the wild i
UAF in Redis 8.2.1 via crafted Lua scripts by authenticated users. EPSS 12.4%. Patch available.
It was discovered, that redis, a persistent key-value database, due to a packaging issue, is prone to a (Debian-specific
Memory Corruption was discovered in the cmsgpack library in the Lua subsystem in Redis before 3.2.12, 4.x before 4.0.10,
Redis is an open source, in-memory database that persists on disk. Versions 8.2.1 and below allow an authenticated user
Redis before 2.8.21 and 3.x before 3.0.2 allows remote attackers to execute arbitrary Lua bytecode via the eval command.
A buffer overflow in Redis 3.2.x prior to 3.2.4 causes arbitrary code execution when a crafted command is sent. Rated cr
Code injection in OneUptime monitoring via custom JS monitor using vm module. PoC and patch available.
In applications using jfinal 4.9.08 and below, there is a deserialization vulnerability when using redis,may be vulnerab
An issue was found in Apache Airflow versions 1.10.10 and below. Rated critical severity (CVSS 9.8), this vulnerability
An Integer Overflow issue was discovered in the struct library in the Lua subsystem in Redis before 3.2.12, 4.x before 4
goanother Another Redis Desktop Manager =<1.6.1 is vulnerable to Cross Site Scripting (XSS) via src/components/Setting.v
Same weakness CWE-287 – Improper Authentication
View allSame technique Authentication Bypass
View allShare
External POC / Exploit Code
Leaving vuln.today
GHSA-c32j-vqhx-rx3x