-
Notifications
You must be signed in to change notification settings - Fork 440
Description
Description
When two different authenticated users concurrently call getAccessToken() with the same (audience, scope), the second call may reuse the first call's in-flight promise and receive the first user's access token. This leaks tokens across sessions and can break authz/isolation guarantees. With DPoP, misuse is limited but the token value still leaks.
The problem stems from the fact that TokenRequestCache computes the cache key from audience + scope only, ignoring the caller's session/user (and DPoP key). The cache is shared per Auth0Client instance; the official guidance encourages a process-wide singleton, so concurrent requests from different users hit the same in-memory cache.
Conditions to exploit:
- A singleton Auth0Client instance
- Two+ users request a token with the same (audience, scope) at the same time on the same runtime/worker.
Reproduction
Log in as User A and User B (separate browsers or sessions).
From both, fire parallel requests to a route that calls auth0.getAccessToken(req, res, { audience: X, scope: '....', refresh: true }).
Observe cases where both responses return identical token, and only User A's session gets persisted changes (if any).
Additional context
Here's an unfinished patch which gives a rough idea of the issue + a path towards a true fix:
diff --git a/src/server/token-request-cache.ts b/src/server/token-request-cache.ts
index dab3a387..ee960abd 100644
--- a/src/server/token-request-cache.ts
+++ b/src/server/token-request-cache.ts
@@ -53,6 +53,7 @@ export abstract class GenericRequestCache<TOptions, TResponse> {
export type TokenRequestCacheOptions = {
options: GetAccessTokenOptions;
authorizationParameters?: AuthorizationParameters;
+ sessionKey?: string;
};
export type TokenRequestCacheResponse = {
@@ -76,10 +77,12 @@ export class TokenRequestCache extends GenericRequestCache<
*/
protected getTokenCacheKey({
options,
- authorizationParameters
+ authorizationParameters,
+ sessionKey
}: {
options: GetAccessTokenOptions;
authorizationParameters?: AuthorizationParameters;
+ sessionKey?: string;
}): string {
const audience =
options.audience ?? authorizationParameters?.audience ?? "";
@@ -88,6 +91,7 @@ export class TokenRequestCache extends GenericRequestCache<
(authorizationParameters?.scope &&
getScopeForAudience(authorizationParameters?.scope, audience)) ??
"";
- return `${audience}:${scope}`;
+ const session = sessionKey ?? "anon";
+ return `${session}:${audience}:${scope}`;
}
}
This bug was found with ZeroPath.
Activity
mrhaddad commentedon Oct 30, 2025
100% also experiencing this issue. Do you have a fix?
tusharpandey13 commentedon Nov 14, 2025
Hi @MegaManSec @mrhaddad
The following patch versions fix this issue in
v4.11.xandv4.12.x:https://github.com/auth0/nextjs-auth0/releases/tag/v4.12.1
https://github.com/auth0/nextjs-auth0/releases/tag/v4.11.2
The same are available in npm.
This issue is not present in versions older than
v4.11.0We will add further communciation on this soon.
tusharpandey13 commentedon Nov 17, 2025
Affected minor versions
v4.11.0,v4.11.1andv4.12.0have been deprecated on npm.