Vulnerability DatabaseCVE-2026-107723

CVE-2026-107723: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-107723 is a silent claim-validator bypass vulnerability in the fast-jwt npm library (by Nearform) that allows an authenticated attacker who can produce or influence a validly-signed JWT to bypass all configured claim validators by crafting a token whose payload is a JSON array instead of an object. It affects all versions up to and including 6.2.4, and was fixed in version 6.3.0. The vulnerability was originally published on July 28, 2026, and added to the GitHub Advisory Database on October 8, 2026. It carries a CVSS v3.1 base score of 8.1 (High) (Github Advisory).

Technical details

The root cause is an improper type validation (CWE-1287) in src/decoder.js. The header validation correctly uses Array.isArray(header) to reject array-typed headers, but the payload check only tests typeof payload !== 'object' — and since typeof [] === 'object' in JavaScript, a JSON array passes this check undetected. When the array payload reaches the verifier's claim-validation loop in src/verifier.js, each validator uses a claim in payload test (e.g., 'exp' in []), which always evaluates to false for arrays (arrays only have numeric indices and length), causing every configured validator — exp, nbf, iss, aud, sub, jti, and nonce — to be silently skipped via continue. This violates RFC 7519 §7.2 step 10, which mandates the JWT Claims Set be a JSON object. The opt-in requiredClaims option would block this bypass, but it is not commonly configured. A prior related fix (GHSA-gm45-q3v2-6cf8 / CVE-2025-30144) addressed array-valued individual claims but did not cover this array-as-payload variant (Github Advisory, fast-jwt PR #639).

Impact

Successful exploitation allows an authenticated attacker holding a valid signing key to forge tokens with array payloads that completely bypass expiry (exp/nbf), issuer (allowedIss), audience (allowedAud), subject (allowedSub), revocation (jti), and OIDC nonce replay protections — while the verifier reports success. This enables creation of forever-tokens, cross-service replay attacks, issuer spoofing in federated/OIDC environments, and revocation-list bypass. Additionally, because payload.sub is undefined for array payloads, authenticated requests become unattributable in audit logs, corrupting the audit trail. The highest-risk deployments include shared-HMAC microservice meshes, multi-tenant SSO backends, and systems with delegated signing where attacker-controlled JSON can influence payload shape (Github Advisory).

Exploitability

No public proof-of-concept exploit has been observed in the wild, and there is no evidence of active exploitation at this time. The EPSS score is 0.0, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. Exploitation requires the attacker to already hold a valid signing key (e.g., a shared HMAC secret) or be able to influence the payload shape at token issuance — meaning the attacker must be an authenticated party within the trust boundary. The GitHub Advisory Database status is "Deferred" for CVE assignment (Github Advisory, Feedly).

Exploitation steps

  1. Obtain a valid signing key: The attacker must already possess or have access to a shared HMAC secret (or equivalent signing credential) used by the target application — for example, as a legitimate microservice participant or tenant in a shared-secret environment.
  2. Craft an array-payload JWT: Construct a JWT where the payload is a JSON array instead of an object. Encode the header and array payload as base64url strings:
    const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64url')
    const payload = Buffer.from(JSON.stringify(['attacker', 'role:admin'])).toString('base64url')
  3. Sign the token: Compute a valid HMAC-SHA256 signature over header.payload using the known secret:
    const sig = crypto.createHmac('sha256', key).update(`${header}.${payload}`).digest('base64url')
    const token = `${header}.${payload}.${sig}`
  4. Submit the forged token: Present the crafted token to any service using fast-jwt's createVerifier with claim-validation options (allowedIss, allowedAud, allowedSub, expiry enforcement, etc.).
  5. Bypass all claim validators: The verifier passes the array through the decoder (since typeof [] === 'object'), then silently skips every configured claim check (because 'exp' in [] === false, etc.), returning the array as a successfully verified payload with no error — effectively granting the attacker access as if all claims were valid (Github Advisory, fast-jwt PR #639).

Indicators of compromise

  • Logs: JWT verification success events where the decoded payload logged by the application is an array (e.g., ["attacker", "role:admin"]) rather than a JSON object; requests where payload.sub is undefined or missing in access logs despite successful authentication.
  • Application Behavior: Authenticated API calls succeeding despite tokens that should have been rejected for expiry, issuer mismatch, or audience mismatch; tokens with no exp, iss, aud, or sub fields being accepted by the verifier.
  • Network: Unusual JWT tokens in Authorization: Bearer headers where the base64url-decoded payload decodes to a JSON array rather than an object; tokens with abnormally long or non-expiring validity windows accepted by services.
  • File System / Code: Presence of fast-jwt versions ≤ 6.2.4 in node_modules/fast-jwt/package.json or package-lock.json (Github Advisory).

Mitigation and workarounds

The primary remediation is to upgrade fast-jwt to version 6.3.0 or later, which adds an explicit Array.isArray(payload) guard in src/decoder.js (commit 86e83ef), mirroring the existing header guard and causing array-payload tokens to be rejected with "The payload must be an object" (fast-jwt v6.3.0, fast-jwt PR #639). As a temporary workaround if immediate upgrade is not possible, add application-layer validation to check that the decoded JWT payload is a plain object (e.g., !Array.isArray(payload)) before accepting it, or enable the requiredClaims option to force claim presence checks that throw on missing claims. Restricting token creation to trusted internal systems only can also reduce the attack surface (Github Advisory).

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

CVE-2026-108261CRITICAL9.3
  • JavaScript logoJavaScript
  • tinacms
NoYesOct 09, 2026
CVE-2026-108259HIGH8.2
  • JavaScript logoJavaScript
  • @tinacms/cli
NoYesOct 09, 2026
CVE-2026-107723HIGH8.1
  • JavaScript logoJavaScript
  • fast-jwt
NoYesOct 08, 2026
CVE-2026-108260HIGH7.6
  • JavaScript logoJavaScript
  • @tinacms/web-components
NoYesOct 09, 2026
CVE-2026-107724HIGH7.4
  • JavaScript logoJavaScript
  • fast-jwt
NoYesOct 08, 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