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

CVE-2026-107722: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-107722 is a JWT algorithm-confusion vulnerability in the fast-jwt npm package (by NearForm) that allows unauthenticated attackers to forge arbitrary JWT tokens by exploiting an incomplete patch for CVE-2026-34950. The flaw affects fast-jwt versions >= 6.2.0 and <= 6.2.4; version 6.3.0 contains the fix. It was published on July 28, 2026, and added to the GitHub Advisory Database on October 8, 2026. The vulnerability carries a CVSS v3.1 base score of 9.8 (Critical) (GitHub Advisory, Feedly).

Technical details

The root cause is CWE-347 (Improper Verification of Cryptographic Signature). The fix for CVE-2026-34950 added key.trim() before PEM detection in src/crypto.js, but String.prototype.trim() only removes ECMAScript-defined whitespace characters. The publicKeyPemMatcher regex (/^-----BEGIN(?: (RSA))? PUBLIC KEY-----/) remains start-anchored (^), so any non-whitespace leading byte — including control characters (NUL, ESC, DEL), zero-width Unicode (U+200B, U+200D), comment prefixes (#, //), HTTP/PGP wrapper text, or arbitrary printable characters — keeps the PEM header off position 0, causing the regex to fail and execution to fall through to the HMAC verification path. The RSA public key is then used as the HMAC shared secret, enabling an attacker who knows the public key (which is public by definition) to sign an HS256 token with that material and have it accepted as authentic. A complete 10-line JavaScript PoC is included in the advisory (GitHub Advisory, Fix PR).

Impact

Successful exploitation allows an unauthenticated remote attacker to forge arbitrary JWT claims — such as admin: true, elevated role, or any sub/tenant-id — that are accepted as valid by any service using fast-jwt 6.2.x without an asymmetric-only algorithm allowlist. This results in complete authentication and authorization bypass, with high confidentiality, integrity, and availability impact. Because fast-jwt is the default JWT backend for @fastify/jwt and is widely used in Fastify-based Node.js APIs, the blast radius is broad; a successful attacker can impersonate any user or gain administrative access to protected resources (GitHub Advisory).

Exploitability

A public proof-of-concept exploit is available in the GitHub Security Advisory itself, consisting of a complete, runnable 10-line JavaScript script verified against fast-jwt 6.2.2 (GitHub Advisory). The attack is fully automatable, requires no authentication or user interaction, and is exploitable over the network. NVD SSVC classifies exploitation status as "poc" with "yes" for automatable and "total" for technical impact. The EPSS score is approximately 0.272% (18th percentile). No in-the-wild exploitation has been observed, and the vulnerability is not currently listed in the CISA KEV catalog (Feedly).

Exploitation steps

  1. Obtain the RSA public key: Retrieve the target service's RSA public key — it is public by definition and may be available via JWKS endpoints, configuration files, or documentation.

  2. Construct a prefixed key string: Prepend a non-whitespace byte to the PEM-encoded public key to defeat the start-anchored regex detection. Example: const key = '# some comment\n' + pem; where pem is the PKCS#1 PEM public key. Any non-whitespace prefix works (control chars, zero-width Unicode, comment lines, HTTP headers, etc.).

  3. Build a forged JWT header and payload: Craft a JWT header specifying alg: 'HS256' and a payload with attacker-chosen claims:

const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url');
const payload = Buffer.from(JSON.stringify({ admin: true, sub: 'attacker' })).toString('base64url');
  1. Sign with HMAC-SHA256 using the prefixed public key as the secret:
const sig = createHmac('sha256', key).update(header + '.' + payload).digest('base64url');
const forgedToken = header + '.' + payload + '.' + sig;
  1. Submit the forged token: Send the forged JWT to the target API in the Authorization: Bearer <forgedToken> header. The fast-jwt verifier, configured without an algorithm allowlist (createVerifier({ key })), misclassifies the prefixed RSA public key as an HMAC secret, computes the same HMAC, and accepts the token — returning the attacker-specified claims (e.g., { admin: true, sub: 'attacker' }) (GitHub Advisory).

Indicators of compromise

  • Network: Unexpected JWT tokens with alg: HS256 presented to endpoints that are configured with RSA/EC public keys; requests from unknown sources carrying tokens with elevated privilege claims (e.g., admin: true) that were not issued by the legitimate identity provider.
  • Logs: Application logs showing successful JWT verification for tokens with alg: HS256 when the service is expected to use RS256/ES256; access log entries for privileged API endpoints from accounts or subjects not previously seen.
  • File System / Configuration: Verification keys loaded from sources with non-standard prefixes (database columns with corrupted encoding, YAML configs with inline comments before PEM headers, copy-pasted PEM blocks with leading metadata).
  • Process / Application Behavior: Unexpected privilege escalation events or admin-level actions performed by accounts that should not have such access; anomalous JWT payloads in application debug logs containing fields like admin: true or unexpected role values (GitHub Advisory).

Mitigation and workarounds

Upgrade immediately to fast-jwt version 6.3.0, which replaces the start-anchored PEM detection with a locatePem() helper that searches for the PEM header anywhere in the key string, ensuring asymmetric keys can never fall back to HMAC regardless of leading content (v6.3.0 Release, Fix Commit). As an immediate workaround for deployments that cannot upgrade, restrict the verifier to an asymmetric-only algorithm allowlist: createVerifier({ key, algorithms: ['RS256'] }) — this prevents HS256 from being inferred or accepted and blocks the attack entirely. Configurations using createVerifier({ key }) (no allowlist) or createVerifier({ key, algorithms: ['HS256'] }) remain vulnerable until patched (GitHub Advisory).

Community reactions

The advisory was credited to researchers DC INFOSEC / n0l3x and EchoSkorJjj, who performed source-code review and end-to-end PoC verification (GitHub Advisory). The NearForm maintainer team coordinated disclosure and released the patch (v6.3.0) simultaneously with the advisory publication to eliminate any window where the exploit was public without a fix available (Fix PR). The fix underwent peer review by maintainer SociableSteve, who confirmed no residual bypass existed after the locatePem() refactor and noted the broader breaking-change implications for callers using PEM-like HMAC secrets.

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