fast-jwt : Silent claim-validator bypass when JWT payload is a JSON array
### Summary `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: ```javascript // src/decoder.js:49 — header check (correct) if (!header || typeof header !== 'object' || Array.isArray(header)) { throw new TokenError(TokenError.codes.malformed, 'The token header is not a valid JSON object.') } // src/decoder.js:65 — payload check (vulnerable) if (!payload || typeof payload !== 'object') { // typeof [] === 'object' throw new TokenError(TokenError.codes.invalidPayload, 'The payload must be an object', { payload }) } Because typeof [] === 'object' in JavaScript, an array payload passes the decoder. In the verifier's validator loop, every check is short-circuited by an in-test that is always false for an array (arrays have only numeric indices and length): // src/verifier.js:304-323 for (const { type, claim, allowed, array, modifier, greater, errorCode, errorVerb } of validators) { const value = payload[claim]
- Products
- fast-jwt
- Affected versions
- Not specified
- Fixed versions
- 6.3.0
- CVEs
- CVE-2026-107723
- Confirmed fixed CVEs
- Not specified
- Updated in this feed
- 28 Oct 2026, 10:06 UTC · Revision 1
Source evidence
fast-jwt : Silent claim-validator bypass when JWT payload is a JSON array
core-osv · Original sourcePublished 8 Oct 2026, 22:01 UTC
### Summary `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: ```javascript // src/decoder.js:49 — header check (correct) if (!header || typeof header !== 'object' || Array.isArray(header)) { throw new TokenError(TokenError.codes.malformed, 'The token header is not a valid JSON object.') } // src/decoder.js:65 — payload check (vulnerable) if (!payload || typeof payload !== 'object') { // typeof [] === 'object' throw new TokenError(TokenError.codes.invalidPayload, 'The payload must be an object', { payload }) } Because typeof [] === 'object' in JavaScript, an array payload passes the decoder. In the verifier's validator loop, every check is short-circuited by an in-test that is always false for an array (arrays have only numeric indices and length): // src/verifier.js:304-323 for (const { type, claim, allowed, array, modifier, greater, errorCode, errorVerb } of validators) { const value = payload[claim]
osv:GHSA-5hjw-83fp-phq9
fast-jwt
Fixed versions: 6.3.0
Complete source record
{
"id": "914273c3b43058ab4f08ee56d4d161eec52d02a3ff0bc49e9268033f1e9fe2ac",
"url": "https://osv.dev/vulnerability/GHSA-5hjw-83fp-phq9",
"method": "structured",
"payload": {
"kind": "advisory",
"title": "fast-jwt : Silent claim-validator bypass when JWT payload is a JSON array",
"summary": "### Summary `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: ```javascript // src/decoder.js:49 — header check (correct) if (!header || typeof header !== 'object' || Array.isArray(header)) { throw new TokenError(TokenError.codes.malformed, 'The token header is not a valid JSON object.') } // src/decoder.js:65 — payload check (vulnerable) if (!payload || typeof payload !== 'object') { // typeof [] === 'object' throw new TokenError(TokenError.codes.invalidPayload, 'The payload must be an object', { payload }) } Because typeof [] === 'object' in JavaScript, an array payload passes the decoder. In the verifier's validator loop, every check is short-circuited by an in-test that is always false for an array (arrays have only numeric indices and length): // src/verifier.js:304-323 for (const { type, claim, allowed, array, modifier, greater, errorCode, errorVerb } of validators) { const value = payload[claim] ",
"evidence": "osv:GHSA-5hjw-83fp-phq9",
"products": [
{
"name": {
"value": "fast-jwt",
"evidence": "/affected/0/package/name"
},
"prerequisites": [],
"fixed_versions": [
{
"value": "6.3.0",
"evidence": "/affected/0/ranges"
}
],
"affected_versions": []
}
],
"severity": "high",
"structured": {
"id": "GHSA-5hjw-83fp-phq9",
"aliases": [
"CVE-2026-107723",
"GHSA-5hjw-83fp-phq9"
],
"metrics": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N"
}
],
"affected": [
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "6.3.0"
}
]
}
],
"package": {
"name": "fast-jwt",
"purl": "pkg:npm/fast-jwt",
"ecosystem": "npm"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-5hjw-83fp-phq9/GHSA-5hjw-83fp-phq9.json",
"last_known_affected_version_range": "<= 6.2.4"
}
}
],
"modified": "2026-10-08T22:15:05.904211357Z",
"provider": "osv",
"references": [
"https://github.com/nearform/fast-jwt/security/advisories/GHSA-5hjw-83fp-phq9",
"https://github.com/nearform/fast-jwt/pull/639",
"https://github.com/nearform/fast-jwt/commit/86e83efd8b5244f50859532d99244f0a9a9a4368",
"https://github.com/nearform/fast-jwt",
"https://github.com/nearform/fast-jwt/releases/tag/v6.3.0"
],
"provider_metadata": {
"cwe_ids": [
"CWE-1287"
],
"severity": "HIGH",
"github_reviewed": true,
"nvd_published_at": null,
"github_reviewed_at": "2026-10-08T22:01:58Z"
}
},
"related_cves": [
{
"value": "CVE-2026-107723",
"evidence": "/aliases"
}
],
"security_relevant": true,
"severity_evidence": "/database_specific/severity"
},
"source_id": "core-osv",
"document_id": 104811,
"published_at": "2026-10-08T22:01:58+00:00"
}