CVE-2026-34950: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-34950 is a JWT algorithm confusion vulnerability in the fast-jwt Node.js library (npm package by NearForm) that allows unauthenticated remote attackers to forge valid JWT tokens by bypassing public key format detection. It affects all versions up to and including 6.1.0, with the fix available in version 6.2.0. The vulnerability is an incomplete fix for CVE-2023-48223 (GHSA-c2ff-88x2-x9pg): the publicKeyPemMatcher regex introduced by that patch uses a ^ anchor that is defeated by any leading whitespace in the key string, re-enabling the same algorithm confusion attack. It was published on April 6, 2026, with a CVSS v3.1 base score of 9.1 (Critical) (GitHub Advisory, Red Hat CVE).

Technical details

The root cause is classified as CWE-327 (Use of a Broken or Risky Cryptographic Algorithm) and CWE-20 (Improper Input Validation). The fix for CVE-2023-48223 changed publicKeyPemMatcher from a plain string .includes() check to the regex /^-----BEGIN(?: (RSA))? PUBLIC KEY-----/, but the ^ anchor requires the match to start at position 0 — any leading whitespace (space, tab, \n, \r\n) causes the regex to fail. In performDetectPublicKeyAlgorithms() in fast-jwt/src/crypto.js, when publicKeyPemMatch is null and the key does not contain an X.509 certificate marker, the function falls through to return hsAlgorithms, misclassifying an RSA public key as an HMAC secret. Critically, the private key detection path calls .trim() before matching, but the public key path does not — this inconsistency is the direct root cause. Leading whitespace in PEM keys is common in real-world deployments (e.g., keys retrieved from PostgreSQL/MySQL text columns, YAML multiline strings, or environment variables) (GitHub Advisory).

Impact

Successful exploitation allows an unauthenticated network attacker to forge arbitrary JWT tokens accepted as valid by the vulnerable server, effectively bypassing all JWT-based authentication. An attacker can craft an HS256-signed token using the server's RSA public key (which is public by definition) and set any payload claims — such as admin: true — enabling full privilege escalation and impersonation of any user. The confidentiality and integrity impacts are both rated High, as attackers can access protected resources and perform unauthorized actions; availability is not directly affected (GitHub Advisory, Feedly).

Exploitability

A fully functional proof-of-concept exploit is publicly available in the GitHub Security Advisory, consisting of two complete Node.js scripts (server.js and attacker.js) that demonstrate the full attack chain — from obtaining a legitimate token to forging an HS256 token with elevated privileges that is accepted by the victim server (GitHub Advisory). The vulnerability requires no authentication, no user interaction, and low attack complexity, making it trivially exploitable by any attacker who knows the server's RSA public key. As of the time of reporting, there is no evidence of in-the-wild exploitation, and the CVE is not listed in the CISA KEV catalog. The EPSS score is approximately 0.021% (0.000210), indicating low current exploitation probability (Feedly). Qualys has detection coverage under detection ID 5010432.

Exploitation steps

  1. Reconnaissance: Identify applications using fast-jwt ≤ 6.1.0 with RS256 JWT verification where the public key may have leading whitespace (e.g., loaded from a database, YAML config, or environment variable).
  2. Obtain the RSA public key: Retrieve the server's RSA public key through any available means — it may be publicly exposed, or recoverable from two JWT tokens using tools like jwt_forgery.py from the rsa_sign2n project (python3 jwt_forgery.py token1 token2).
  3. Obtain a legitimate token: Request a valid JWT from the server's token generation endpoint (e.g., GET /generateToken?name=attacker) to confirm the server is using RS256.
  4. Craft a forged HS256 token: Construct a JWT header {"alg": "HS256", "typ": "JWT"} and a payload with elevated claims (e.g., {"admin": true}). Sign the token using HMAC-SHA256 with the RSA public key (including its leading whitespace) as the HMAC secret: createHmac('sha256', publicKey).update(header + '.' + payload).digest('base64url').
  5. Submit the forged token: Present the forged HS256 token to the protected endpoint (e.g., GET /checkAdmin?token=<forged_token>). Because the leading whitespace defeats the ^ anchor in publicKeyPemMatcher, the library misclassifies the RSA key as an HMAC secret and accepts the HS256 signature, returning the elevated-privilege response (GitHub Advisory).

Indicators of compromise

  • Network: Unexpected JWT tokens with "alg": "HS256" presented to endpoints that are configured to use RS256; requests to protected endpoints from users/IPs that have not previously authenticated via the normal token issuance flow.
  • Logs: Application logs showing successful JWT verification for tokens with alg=HS256 on endpoints expected to use RS256; sudden privilege escalation events (e.g., admin: true) in access logs for accounts that were previously non-admin.
  • Application Behavior: JWT verification succeeding for tokens where the algorithm in the header does not match the configured signing algorithm; absence of algorithm mismatch errors in cases where they would be expected.
  • File System / Config: Public key PEM files or database-stored keys that contain leading whitespace characters (\n, \r\n, spaces, or tabs) before the -----BEGIN PUBLIC KEY----- header — these are the precondition for exploitation (GitHub Advisory).

Mitigation and workarounds

The primary remediation is to upgrade fast-jwt to version 6.2.0 or later, which corrects the regex to handle leading whitespace (consistent with the .trim() already applied in the private key detection path) (GitHub Advisory). As an immediate workaround prior to patching, ensure that all public key strings are trimmed before being passed to fast-jwt (e.g., publicKey.trim()), and explicitly specify the algorithm option when calling createVerifier() to prevent algorithm confusion. Additionally, audit all JWT sessions that may have been issued or accepted during the vulnerable period and invalidate them if unauthorized access is suspected (Feedly).

Community reactions

The Hacker Wire published a dedicated write-up on the vulnerability titled "fast-jwt Algorithm Confusion Re-Enabled — CVE-2026-34950," providing technical context and coverage of the incomplete fix (The Hacker Wire). The advisory was credited to researcher rtvkiz and published by antoatta85 on the NearForm GitHub repository. Red Hat also tracked the CVE in their security advisory database (Red Hat CVE). Community reaction has focused on the irony of the incomplete patch — the fix for CVE-2023-48223 introduced a subtly broken regex that re-enabled the exact same class of attack it was meant to prevent.

Additional resources


Source: This report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-gvwc-5hr5-44p8HIGH7.5
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-5jh3-w3fj-6758LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-5v8x-rm7w-m4c7LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-7pqp-3q23-mwr8LOW3.7
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026
GHSA-3qg4-7mq2-gm93MEDIUMN/A
  • JavaScript logoJavaScript
  • probe-image-size
NoYesOct 26, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management