GitHub Security Advisory: GHSA-rp9m-7r4c-75qg
Package: fast-jwt (NPM)
Severity: CRITICAL (CVSS 9.1)
CWE: CWE-345: Insufficient Verification of Data Authenticity, CWE-706: Use of Incorrectly-Resolved Name or Reference, CWE-1289: Improper Validation of Unsafe Equivalence in Input
Vulnerable versions: >= 0.0.1, < 6.2.0
Patched in: 6.2.0

Summary: fast-jwt: Cache Confusion via cacheKeyBuilder Collisions Can Return Claims From a Different Token (Identity/Authorization Mixup)

Details:
_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 wrong user identity

## Affected Configurations

This vulnerability ONLY affects applications that BOTH:

1. Enable caching using the cache option
2. Use custom cacheKeyBuilder functions that can produce collisions

VULNERABLE examples:
```
// Collision-prone: same audience = same cache key
cacheKeyBuilder: (token) => {
  const { aud } = parseToken(token)
  return `aud=${aud}`
}

// Collision-prone: grouping by user type
cacheKeyBuilder: (token) => {
  const { aud } = parseToken(token)
  return aud.includes('admin') ? 'admin-users' : 'regular-users'
}

// Collision-prone: tenant + service grouping
cacheKeyBuilder: (token) => {
  const { iss, aud } = parseToken(token)
  return `${iss}-${aud}`
}
```

SAFE examples:
```
// Default hash-based (recommended)
createVerifier({ cache: true })  // Uses secure default

// Include unique user identifier
cacheKeyBuilder: (token) => {
  const { sub, aud, iat } = parseToken(token)
  return `${sub}-${aud}-${iat}`
}

// No caching (always safe)
createVerifier({ cache: false })
```
### Not Affected

- Applications using **default caching**
- Applications with **caching disabled**
 
## Assessment Guide

To determine if you're affected:

1. Check if caching is enabled: Look for cache: true or cache: <number> in verifier configuration
2. Check for custom cache key builders: Look for cacheKeyBuilder function in configuration
3. Analyze collision potential: Review if your cacheKeyBuilder can produce identical keys for different users/tokens
4. If no custom cacheKeyBuilder: You are NOT affected (default is safe)

## Mitigations

Mitigations include:

- Ensure uniqueness of keys produced in cacheKeyBuilder
- Remove custom cacheKeyBuilder method
- Disable caching

---

fast-jwt allows enabling a verification cache through the cache option.
The cache key is derived from the token via cacheKeyBuilder.

When a custom cacheKeyBuilder produces collisions between different tokens, the verifier may return the cached payload of a previous token