PHP2Shell: Read our blog on the critical RCE vulnerabilities affecting 70% of the Internet
Vulnerability DatabaseCVE-2026-107720

CVE-2026-107720: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-107720 is an authentication bypass vulnerability in the fast-jwt npm library (by NearForm) where createVerifier accepts unsigned JWTs when the key option is an empty string ('') or null and the algorithms option is set to a non-empty allowlist. This affects all versions of fast-jwt up to and including 6.3.0. The vulnerability was published on July 30, 2026, and added to the GitHub Advisory Database on October 8, 2026. It carries a CVSS v3.1 base score of 7.4 (High) (Github Advisory).

Technical details

The root cause involves four cooperating code paths in src/verifier.js (CWE-20: Improper Input Validation; CWE-347: Improper Verification of Cryptographic Signature). When key is '' (a string) or null (an object), the outer typeof check passes but the if (key && ...) guard never invokes prepareKeyOrSecret, so the empty-secret rejection is never reached. With a falsy key, auto-detection is skipped and the caller-supplied algorithms allowlist remains active. Because hasKey evaluates to false, an unsigned token (with an empty signature segment, e.g., header.payload.) bypasses both the missingSignature and missingKey branches. Finally, the verifySignature call is gated on signature being truthy, so an empty signature causes the gate to evaluate to false and cryptographic verification is never performed — the forged payload is returned as verified. This behavior is particularly dangerous in applications that read JWT secrets from environment variables with a fallback (e.g., process.env.JWT_SECRET || '') and also set an explicit algorithms allowlist as a security best practice (Github Advisory, GitHub PR #649).

Impact

Successful exploitation results in a full authentication and authorization bypass: an unauthenticated network attacker can forge a JWT with arbitrary claims (e.g., admin: true, role: 'root', any sub) and have it accepted as valid by the application. This allows impersonation of any user, privilege escalation, and unauthorized access to protected resources. Confidentiality and integrity impacts are both rated High, as the attacker can access and manipulate data gated behind JWT-based authentication. Availability is not directly impacted. Claim validators (e.g., exp, allowedSub) still execute, but signature verification is entirely skipped (Github Advisory).

Exploitability

A public proof-of-concept (PoC) JavaScript script (poc-empty-key-bypass.js) is included in the security advisory and demonstrates the bypass by crafting unsigned tokens and verifying them against the vulnerable library (Github Advisory). The EPSS score is approximately 0.256% (16th percentile), indicating a relatively low but non-negligible probability of exploitation in the near term. No in-the-wild exploitation has been reported, and the vulnerability is not listed in the CISA KEV catalog. Exploitation requires no authentication or user interaction, but does require the target application to be configured with a falsy synchronous key and a non-empty algorithms allowlist — a specific but realistic misconfiguration.

Exploitation steps

  1. Identify target: Locate an application using fast-jwt ≤ 6.3.0 with createVerifier configured with key: '' or key: null and a non-empty algorithms allowlist (e.g., ['HS256']). This is common when JWT secrets are read from unset environment variables via patterns like process.env.JWT_SECRET || ''.
  2. Craft an unsigned JWT: Construct a JWT with attacker-controlled claims by base64url-encoding a header (e.g., {alg: 'HS256', typ: 'JWT'}) and a payload (e.g., {sub: 'attacker', admin: true, role: 'root'}), then joining them with a trailing dot to produce an empty signature segment: <header>.<payload>.
    function unsigned(alg, claims) {
      const h = Buffer.from(JSON.stringify({ alg, typ: 'JWT' })).toString('base64url')
      const p = Buffer.from(JSON.stringify(claims)).toString('base64url')
      return `${h}.${p}.` // trailing dot = empty signature
    }
    const token = unsigned('HS256', { sub: 'attacker', admin: true, role: 'root' })
  3. Submit the forged token: Send the crafted token to the target application in the Authorization: Bearer <token> header or equivalent JWT input field.
  4. Bypass verification: The vulnerable createVerifier skips prepareKeyOrSecret, retains the algorithms allowlist, sees hasKey = false and signature = '', and skips the verifySignature gate entirely — returning the forged payload as verified.
  5. Achieve unauthorized access: The application trusts the returned claims (e.g., admin: true) and grants the attacker elevated privileges or access to protected resources (Github Advisory).

Indicators of compromise

  • Network: Unusual or repeated JWT-authenticated requests to privileged API endpoints from unexpected IP addresses or user agents; requests where the JWT payload contains elevated claims (e.g., admin: true, role: 'root') not associated with legitimate users.
  • Logs: Application logs showing successful JWT verification for tokens with suspicious or unexpected claim values; JWT tokens in access logs where the signature segment is empty (token ends with a trailing dot, e.g., eyJ...eyJ...).
  • Application Behavior: Successful authorization for actions that should require elevated privileges from accounts that do not hold those privileges; unexpected admin-level operations performed by low-privilege or unknown user identifiers (sub values).
  • File System / Config: Evidence of JWT_SECRET or equivalent environment variable being unset or empty in application configuration, combined with an explicit algorithms allowlist in verifier configuration.

Mitigation and workarounds

Upgrade fast-jwt to version 6.3.1 or later immediately; this version validates the key option at verifier construction time and throws FAST_JWT_INVALID_KEY if a falsy synchronous key is paired with any non-none algorithm allowlist (Release v6.3.1, GitHub PR #649). As an interim measure, audit all uses of createVerifier to ensure the key option is never an empty string or null — replace patterns like process.env.JWT_SECRET || '' with explicit validation that throws an error if the secret is missing. Additionally, implement defense-in-depth by adding application-level authentication checks independent of JWT verification, and audit logs for tokens with empty signature segments or unexpected elevated claims.

Community reactions

The vulnerability was reported by security researcher Char0n1507 and published by SociableSteve (a NearForm contributor) directly to the fast-jwt repository on July 30, 2026, with a detailed advisory and PoC included (Github Advisory). The maintainer (lv10) independently verified the vulnerability before approving the fix, confirming that createVerifier({ key: '', algorithms: ['HS256'] }) accepted forged tokens on the unpatched version. The fix was merged and released the same day as the advisory, reflecting a rapid response. No significant broader media coverage or social media discussion has been identified beyond the GitHub advisory and standard vulnerability database entries.

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-jr5w-w6x2-84p9HIGH7.4
  • JavaScript logoJavaScript
  • electron
NoYesOct 22, 2026
GHSA-v9q2-hcqj-ggqrMEDIUMN/A
  • JavaScript logoJavaScript
  • seamless-auth-api
NoYesOct 22, 2026
GHSA-v2q2-q246-8chmMEDIUMN/A
  • JavaScript logoJavaScript
  • seamless-auth-api
NoYesOct 22, 2026
GHSA-qx82-28gf-w744HIGHN/A
  • JavaScript logoJavaScript
  • seamless-auth-api
NoYesOct 22, 2026
GHSA-9xg2-j8fg-427cMEDIUMN/A
  • JavaScript logoJavaScript
  • seamless-auth-api
NoYesOct 22, 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

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