Skip to main content

ruby-jwt CVE-2026-45363

CRITICAL
Improper Authentication (CWE-287)
2026-05-18 https://github.com/jwt/ruby-jwt GHSA-c32j-vqhx-rx3x
9.1
CVSS 3.1 · Vendor: https://github.com/jwt/ruby-jwt
Share

Severity by source

Vendor (https://github.com/jwt/ruby-jwt) PRIMARY
9.1 CRITICAL
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
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

5
Re-analysis Queued
Jul 14, 2026 - 22:22 vuln.today
cvss_changed
Severity Changed
Jul 14, 2026 - 22:22 NVD
HIGH CRITICAL
CVSS changed
Jul 14, 2026 - 22:22 NVD
7.4 (HIGH) 9.1 (CRITICAL)
Source Code Evidence Fetched
May 18, 2026 - 18:00 vuln.today
Analysis Generated
May 18, 2026 - 18:00 vuln.today

DescriptionCVE.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) == 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:)

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.

More in Redis

View all
CVE-2026-48172 CRITICAL POC
10.0 May 21

LiteSpeed User-End cPanel Plugin before 2.4.5 allows privilege escalation (possibly to root), as exploited in the wild i

CVE-2025-49844 CRITICAL POC
9.9 Oct 03

UAF in Redis 8.2.1 via crafted Lua scripts by authenticated users. EPSS 12.4%. Patch available.

CVE-2022-0543 CRITICAL POC
10.0 Feb 18

It was discovered, that redis, a persistent key-value database, due to a packaging issue, is prone to a (Debian-specific

CVE-2018-11218 CRITICAL POC
9.8 Jun 17

Memory Corruption was discovered in the cmsgpack library in the Lua subsystem in Redis before 3.2.12, 4.x before 4.0.10,

CVE-2025-46817 HIGH POC
7.0 Oct 03

Redis is an open source, in-memory database that persists on disk. Versions 8.2.1 and below allow an authenticated user

CVE-2015-4335 CRITICAL POC
10.0 Jun 09

Redis before 2.8.21 and 3.x before 3.0.2 allows remote attackers to execute arbitrary Lua bytecode via the eval command.

CVE-2016-8339 CRITICAL POC
9.8 Oct 28

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

CVE-2026-27574 CRITICAL POC
9.9 Feb 21

Code injection in OneUptime monitoring via custom JS monitor using vm module. PoC and patch available.

CVE-2021-31649 CRITICAL POC
9.8 Jun 24

In applications using jfinal 4.9.08 and below, there is a deserialization vulnerability when using redis,may be vulnerab

CVE-2020-11981 CRITICAL POC
9.8 Jul 17

An issue was found in Apache Airflow versions 1.10.10 and below. Rated critical severity (CVSS 9.8), this vulnerability

CVE-2018-11219 CRITICAL POC
9.8 Jun 17

An Integer Overflow issue was discovered in the struct library in the Lua subsystem in Redis before 3.2.12, 4.x before 4

CVE-2024-23998 CRITICAL POC
9.6 Jul 05

goanother Another Redis Desktop Manager =<1.6.1 is vulnerable to Cross Site Scripting (XSS) via src/components/Setting.v

Share

CVE-2026-45363 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy