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
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify Ruby app accepting JWTs
  2. Delivery
    Probe for HS256 acceptance and key-lookup miss behavior
  3. Exploit
    Craft token signed with empty-string HMAC key
  4. Execution
    Submit forged JWT to authenticated endpoint
  5. Persist
    Library verifies under empty key
  6. Impact
    Impersonate arbitrary user or role

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V6 - Authentication Authentication mechanism validation
MITRE ATT&CK

2 techniques across 2 tactics: Defense Evasion, Initial Access

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Exploitation requires the target application to be running ruby-jwt < 3.2.0 with HS256/HS384/HS512 verification AND to supply an empty string ('') or nil as the verification key - either as the positional argument to JWT.decode, as the return value of a keyfinder block, or via the key_finder: argument to JWT::EncodedToken#verify_signature!. Concretely vulnerable patterns named in the advisory: redis.get("kid:#{kid}").to_s on a cache miss, ORM string columns declared with default: '', ENV['SECRET'] || '', Hash.new('') lookups for unknown kids, and [primary, fallback] key arrays where fallback may be nil. Limiting factors: applications that pass a non-empty static key, whose keyfinder returns literal nil (rejected by find_key), or that have enabled the non-default enforce_hmac_key_length option are NOT exploitable. The CVSS AC:H reflects that the attacker must identify or guess that the target falls into one of the unsafe key-resolution patterns; PR:N confirms no prior authentication is needed once that condition holds.

Impact

CVSS 7.4 (AV:N/AC:H/PR:N/UI:N/C:H/I:H/A:N) reflects high confidentiality and integrity impact against unauthenticated network attackers, with AC:H acknowledging that exploitability depends on a specific application-side condition (the verification key resolving to '' or nil). No EPSS, KEV, or POC data was provided, so per policy this is treated as no public exploit identified at time of analysis - not a contradiction of the high CVSS, but a signal that mass exploitation is not yet observed. Real-world risk is bimodal: applications passing a non-empty static secret are unaffected, but those using Redis-backed kid lookups (redis.get("kid:#{kid}").to_s), ORM columns defaulting to '', ENV['SECRET'] || '', Hash.new(''), or [primary, fallback]-with-nil patterns are trivially bypassable. The enforce_hmac_key_length option would have blocked this but ships disabled by default, so most deployments are exposed until upgraded. Defenders should treat this as a high-priority library upgrade for any Ruby service handling JWT-based auth, even without active-exploitation signals.

Exploit ScenarioDerived

An attacker crafts a JWT with header {"alg":"HS256"}, an arbitrary payload (e.g. {"user_id":1,"role":"admin"}), and a signature computed via HMAC-SHA256 using an empty key. They submit the token to a vulnerable Rails API whose authentication middleware looks up the signing key from Redis by kid - redis.get("kid:#{kid}").to_s returns '' on a cache miss - and ruby-jwt < 3.2.0 verifies the forged token, granting admin access without credentials. No public PoC was provided, but the advisory's two-line reproducer makes weaponization trivial for any affected deployment pattern.

Act Now Prioritize within 24-48h. Why: CRITICAL severity.
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – May 18, 2026

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.

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.

Affected Packages

rubygems jwt fix: 2.10.3, 3.2.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in rubygems

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

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.

Know when OpenSSL gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

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
SUSE 7.4 HIGH
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Red Hat 7.4 HIGH

Primary rating from Vendor (https://github.com/jwt/ruby-jwt).

CVSS VectorVendor: https://github.com/jwt/ruby-jwt

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

2
Severity Changed
Jul 14, 2026 - 22:22 NVD
HIGH CRITICAL
CVSS changed
Jul 14, 2026 - 22:22 NVD
7.4 (HIGH) 9.1 (CRITICAL)

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:)

Executive ViewAI

Why It Matters

The ruby-jwt library (versions prior to 3.2.0) contains an authentication bypass vulnerability allowing remote attackers to forge cryptographic tokens used for API authentication and session management. Applications relying on this library-particularly those with empty or nil key fallback patterns (common in Redis caching, ORM defaults, and environment variable fallbacks)-face significant risk of unauthorized system access and data exposure. This affects any Ruby-based service using vulnerable versions for token verification.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.0%
Top 95% exploitable
Threat Intel
1
1 source
Data Quality
6 sources
Confidence: High
NVD CVE.org EPSS GHSA Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC No
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
High

Priority Score

46
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +46
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

Affected Products (CPE)CVE.org

pkg:rubygems/jwt
CVE-2014-0160 HIGH POC
7.5 Apr 07

The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packe

CVE-2021-3711 CRITICAL POC
9.8 Aug 24

In order to decrypt SM2 encrypted data an application is expected to call the API function EVP_PKEY_decrypt(). Rated cri

CVE-2014-0195 MEDIUM POC
6.8 Jun 05

The dtls1_reassemble_fragment function in d1_both.c in OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2016-0800 MEDIUM POC
5.9 Mar 01

The SSLv2 protocol, as used in OpenSSL before 1.0.1s and 1.0.2 before 1.0.2g and other products, requires a server to se

CVE-2015-0204 MEDIUM POC
4.3 Jan 09

The ssl3_get_key_exchange function in s3_clnt.c in OpenSSL before 0.9.8zd, 1.0.0 before 1.0.0p, and 1.0.1 before 1.0.1k

CVE-2022-2068 HIGH
7.3 Jun 21

In addition to the c_rehash shell command injection identified in CVE-2022-1292, further circumstances where the c_rehas

CVE-2015-4000 LOW POC
3.7 May 21

The TLS protocol 1.2 and earlier, when a DHE_EXPORT ciphersuite is enabled on a server but not on a client, does not pro

CVE-2014-3566 LOW POC
3.4 Oct 15

The SSL protocol 3.0, as used in OpenSSL through 1.0.1i and other products, uses nondeterministic CBC padding, which mak

CVE-2016-2107 MEDIUM POC
5.9 May 05

The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a

CVE-2015-1793 MEDIUM POC
6.5 Jul 09

The X509_verify_cert function in crypto/x509/x509_vfy.c in OpenSSL 1.0.1n, 1.0.1o, 1.0.2b, and 1.0.2c does not properly

CVE-2022-3602 HIGH
7.5 Nov 01

A buffer overrun can be triggered in X.509 certificate verification, specifically in name constraint checking. Rated hig

Vendor StatusVendor

SUSE

Severity: Important

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