Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
13 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
cacheSet only derives its exp cache deadline inside hasIat (src/verifier.js:127-140). JWT iat is optional. For a valid token with exp but no iat, cacheSet substitutes clockTimestamp + clockTolerance + cacheTTL (src/verifier.js:142-146). Later, the cache path returns the saved payload before decoding or invoking verifyToken (src/verifier.js:372-388). Since expiration validation is in verifyToken, the expired token remains accepted until the cache deadline. Details The bug is an expiration-check bypass caused by caching. Normally, verification works like this: 1. Verify signature. 2. Check exp against the current time. 3. Return the JWT claims. With caching enabled, fast-jwt saves successful verification results so it can avoid repeating crypto work for the same token. The intended invariant is: A cached token must stop being accepted at the same time as a non-cached token. But the cache computes its expiration incorrectly. In fast-jwt/src/verifier.js:127, the code first checks…
Recommended action: Upgrade to 6.3.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
createVerifier in fast-jwt ≤ 6.3.0 skips signature verification entirely when the key option is a falsy synchronous value ('' or null) and the algorithms option is set to a non-empty allowlist. An attacker who can present a JWT to the application — regardless of algorithm — can forge arbitrary claims without possessing any signing key. Details Root cause — four cooperating code paths: A. Falsy sync keys bypass prepareKeyOrSecret createVerifier branches on typeof key: When key is '' (string, falsy) or null (object, falsy) the outer type check passes but the if (key && ...) guard never calls prepareKeyOrSecret. The empty-secret rejection added in that function is therefore never reached for sync keys: B. Explicit algorithms keeps an allowlist active with no key When key is falsy, autodetection is skipped and the caller-supplied algorithms (e.g. ['HS256']) is retained in allowedAlgorithms. The verifier therefore accepts tokens whose header matches that list. C. hasKey is false →…
Recommended action: Upgrade to 6.3.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fix for CVE-2026-34950 (CVSS 9.1, released in v6.2.0) is incomplete. It adds key.trim() to the PEM-detection path in src/crypto.js, but String.prototype.trim() only strips characters classified as whitespace by the ECMAScript specification. The subsequent ^-anchored regex (/^-----BEGIN(?: (RSA))? PUBLIC KEY-----/) still requires the PEM header at position 0 — so any non-whitespace leading byte (control chars, zero-width unicode, comments, HTTP-style headers, PGP wrappers) bypasses detection and falls through to the HMAC verification path, using the RSA public key as the HMAC shared secret. Net result: the exact same RSA→HS256 algorithm-confusion attack the original CVE addressed is fully re-enabled with a slightly different leading byte. Attack prerequisites are identical to CVE-2026-34950: attacker knows the target's public RSA key (which is public by definition), and the target loads that key from a source whose content may have a non-whitespace prefix (DB column with…
Recommended action: Upgrade to 6.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
createVerifier({ clockTolerance: Infinity }) silently bypasses both exp (expiry) AND nbf (not-before) validation. Any expired or not-yet-active token is accepted as valid. The same primitive also corrupts the verifier's internal cache so cached entries inherit infinite validity — they remain valid past a later developer-removed Infinity config until LRU eviction. Vulnerable code src/verifier.js:531-533 — option validation only rejects negative values, not Infinity: Infinity passes (it's a number, not less than 0, truthy). src/verifier.js:583-602 — clockTolerance flows into the date-claim validators: src/verifier.js:198-205 — applies modifier additively, producing always-pass comparisons: Empirical PoC Verified against fast-jwt@HEAD on 2026-06-03 (commit pulled today). Cache side-effect The verifier's LRU cache uses clockTolerance to compute the cache entry's expiry window: src/verifier.js:121-134: With clockTolerance: Infinity, cache entries are stored with min=-Infinity,…
Recommended action: Upgrade to 6.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
fast-jwt's createVerifier silently skips all configured claim validators (exp, nbf, iss, aud, sub, jti, nonce) when a validly-signed JWT carries a JSON array as its payload instead of an object. The verifier reports success while having enforced only the signature. This breaks the library's documented allowedIss / allowedAud / allowedSub / expiry / replay-protection guarantees and violates RFC 7519 §7.2 step 10, which requires the JWT Claims Set to be a JSON object. Details The decoder validates the header is a non-array object but the payload check is missing the Array.isArray guard: PoC Suggested patch (src/decoder.js:65): - if (!payload || typeof payload !== 'object') { + if (!payload || typeof payload !== 'object' || Array.isArray(payload)) { throw new TokenError(TokenError.codes.invalidPayload, 'The payload must be an object', { payload }) } This mirrors the existing header guard at line 49. Impact Type: Silent authorization-validator bypass. When a validly-signed JWT…
Recommended action: Upgrade to 6.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
fast-jwt 6.2.4 silently classifies raw serialized public JWK JSON as an HMAC secret. If an application supplies public JWK JSON text as the verifier key and HS256 is explicitly allowed or automatically inferred, an attacker who knows the same public JSON text can use it as an HMAC key and create an arbitrary HS256 token that fast-jwt accepts as valid. This can result in authentication or authorization bypass through forged JWT claims. The PoC demonstrates the issue with a serialized RSA public JWK. The same non-PEM classification also applies to raw JWKS JSON text, although the attached standalone PoC focuses on the smallest JWK case. Details The verifier accepts a string or Buffer as key material. In src/crypto.js, performDetectPublicKeyAlgorithms() attempts to infer the permitted algorithm family from the supplied string. Strings matching supported PEM public-key formats are classified as asymmetric keys. Any other non-empty string is assumed to be an HMAC secret: js…
Recommended action: Upgrade to 6.3.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
A critical authentication-bypass vulnerability in fast-jwt's async key-resolver flow allows any unauthenticated attacker to forge arbitrary JWTs that are accepted as authentic. When the application's key resolver returns an empty string (''), for example via the common keys[decoded.header.kid] || '' JWKS-style fallback, fast-jwt converts it to a zero-length Buffer, hands it to crypto.createSecretKey, derives allowedAlgorithms = ['HS256','HS384','HS512'] from it, and then verifies the token's signature against an empty-key HMAC. The attacker simply computes HMAC-SHA256(key='', input='${header}.${payload}'), which Node accepts without complaint — and the verifier returns the attacker-chosen payload (sub, admin, scopes, etc.) as authentic. Reproducible 100% against the current latest release fast-jwt@6.2.3. Preconditions For this issue to occur the following MUST ALL be true: 1. The application developer (library consumer) uses an asynchronous callback function to set the key…
Recommended action: Upgrade to 6.2.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
⚠️ IMPORTANT CLARIFICATIONS Affected Configurations This vulnerability ONLY affects applications that: - Use RegExp objects (not strings) in the allowedAud, allowedIss, allowedSub, allowedJti, or allowedNonce options - Configure patterns susceptible to catastrophic backtracking - Example: allowedAud: /^(a+)+X$/ ← VULNERABLE - Example: allowedAud: "api.company.com" ← SAFE Not Affected - Applications using string patterns for audience validation (most common) - Applications using safe RegExp patterns without nested quantifiers - Default fast-jwt configurations Assessment Guide To determine if you're affected: 1. Check ifallowedAud, allowedIss, allowedSub, allowedJti, or allowedNonce use RegExp objects (/pattern/ or new RegExp()) 2. If yes, review the pattern for nested quantifiers like (a+)+, (.), etc. 3. If no RegExp usage, you are NOT affected ------ <html <body <!--StartFragment--<h2 data-start="218" data-end="228"Summary</h2 <p data-start="230" data-end="364"A…
Recommended action: Upgrade to 6.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Using certain modifiers on RegExp objects in the allowedAud, allowedIss, allowedSub, allowedJti, or allowedNonce options in verify functions can cause certain unintended behaviours. This is because some modifiers are stateful and will cause failures in every second verification attempt regardless of the validity of the token provided. Such modifiers are: - /g : Global matching - /y : Sticky matching This does NOT allow invalid tokens to be accepted, only for valid tokens to be improperly rejected in some configurations. Instead it causes 50% of valid authentication requests to fail in an alternating pattern, leading to: - Intermittent user authentication failures - Potential retry storms in applications - Operational monitoring alerts Affected Configurations This vulnerability ONLY affects applications that: - Use RegExp objects (not strings) in the allowedAud, allowedIss, allowedSub, allowedJti, or allowedNonce options - Use stateful RegExp modifiers such a /g or /y Example:…
Recommended action: Upgrade to 6.2.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
NOTE: While the library exposes a mechanism which could introduce the vulnerability, this issue is created by developer-supplied code and not by the library itself. We will add a warning and some education for users around the possible issues however since the defaults work we will not be updating the library beyond that for this advisory. Impact Setting up a custom cacheKeyBuilder method which does not properly create unique keys for different tokens can lead to cache collisions. This could cause tokens to be mis-identified during the verification process leading to: - Valid tokens returning claims from different valid tokens - Users being mis-identified as other users based on the wrong token This could result in: - User impersonation - UserB receives UserA's identity and permissions - Privilege escalation - Low-privilege users inherit admin-level access - Cross-tenant data access - Users gain access to other tenants' resources - Authorization bypass - Security decisions made on…
Recommended action: Upgrade to 6.2.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fix for GHSA-c2ff-88x2-x9pg (CVE-2023-48223) is incomplete. The publicKeyPemMatcher regex in fast-jwt/src/crypto.js uses a ^ anchor that is defeated by any leading whitespace in the key string, re-enabling the exact same JWT algorithm confusion attack that the CVE patched. Details The fix for CVE-2023-48223 (https://github.com/nearform/fast-jwt/commit/15a6e92, v3.3.2) changed the public key matcher from a plain string used with .includes() to a regex used with .match(): When the key string has any leading whitespace (space, tab, \n, \r\n), the ^ anchor fails, publicKeyPemMatch is null, and the RSA public key is classified as an HMAC secret (hsAlgorithms). The attacker can then sign an HS256 token using the public key as the HMAC secret — the exact same attack as CVE-2023-48223. Notably, the private key detection function does call .trim() before matching https://github.com/nearform/fast-jwt/blob/0ff14a687b9af786bd3ffa870d6febe6e1f13aaa/src/crypto.js#L79: const pemData =…
Recommended action: Upgrade to 6.2.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fast-jwt library does not properly validate the iss claim based on the RFC https://datatracker.ietf.org/doc/html/rfc7519#page-9. Details The iss (issuer) claim validation within the fast-jwt library permits an array of strings as a valid iss value. This design flaw enables a potential attack where a malicious actor crafts a JWT with an iss claim structured as ['https://attacker-domain/', 'https://valid-iss']. Due to the permissive validation, the JWT will be deemed valid. Furthermore, if the application relies on external libraries like get-jwks that do not independently validate the iss claim, the attacker can leverage this vulnerability to forge a JWT that will be accepted by the victim application. Essentially, the attacker can insert their own domain into the iss array, alongside the legitimate issuer, and bypass the intended security checks. PoC Take a server running the following code: Now we build a server that will be used to generate the JWT token and send the…
Recommended action: Upgrade to 5.0.6 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The fast-jwt library does not properly prevent JWT algorithm confusion for all public key types. Details The 'publicKeyPemMatcher' in 'fast-jwt/src/crypto.js' does not properly match all common PEM formats for public keys. To exploit this vulnerability, an attacker needs to craft a malicious JWT token containing the HS256 algorithm, signed with the public RSA key of the victim application. This attack will only work if the victim application utilizes a public key containing the BEGIN RSA PUBLIC KEY header. PoC Take a server running the following code: Assume the server generated their keys like follows: Public key recovery First, an attacker needs to recover the public key from the server in any way possible. It is possible to extract this from just two JWT tokens as shown below. Grab two different JWT tokens and utilize the following tool: https://github.com/silentsignal/rsasign2n/blob/release/standalone/jwtforgery.py The tool will generate 4 different public keys, all in…
Recommended action: Upgrade to 3.3.2 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.