CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-40155
5.40.04%

CVE-2026-40155: Race Condition in Auth0 Next.js SDK DPoP Proxy Fetcher

Alon Barad
Alon Barad
Software Engineer

Apr 21, 2026·7 min read·4 visits

PoC Available

Executive Summary (TL;DR)

The Auth0 Next.js SDK improperly shares stateful fetcher instances across concurrent proxy requests when handling DPoP challenges. This race condition can result in cross-session data exposure. Upgrading to version 4.18.0 resolves the issue by securely scoping cryptographic handles to individual requests.

A race condition vulnerability in the Auth0 Next.js SDK (versions 4.12.0 through 4.17.1) leads to improper proxy cache lookups during Demonstrating Proof-of-Possession (DPoP) nonce retries. This flaw allows concurrent proxy requests to cross-pollinate state, potentially exposing sensitive session data to the wrong client.

Vulnerability Overview

The @auth0/nextjs-auth0 package provides integration between the Next.js framework and Auth0 authentication services. The SDK includes proxy handlers, specifically mapped to /me/* and /my-org/* routes, which facilitate secure communication between the client application and the upstream Auth0 tenant. These handlers abstract the complexity of attaching access tokens to outbound requests.

Demonstrating Proof-of-Possession (DPoP) is an application-level security mechanism designed to bind access tokens to specific cryptographic keys, preventing token theft and replay attacks. When DPoP is enabled, the SDK must handle dynamic cryptographic challenges. If the server issues a 401 Unauthorized response containing a DPoP-Nonce header, the SDK must transparently generate a new proof and retry the request.

CVE-2026-40155 occurs due to a concurrency flaw within this DPoP retry mechanism. The SDK utilizes a global Least Recently Used (LRU) cache to manage fetcher objects intended to handle these outbound proxy requests. This design introduces a time-of-check to time-of-use (TOCTOU) race condition when multiple requests execute simultaneously.

The vulnerability is classified under CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization). Impact is isolated to environments explicitly utilizing the proxy handlers in conjunction with DPoP. Successful exploitation results in improper state synchronization, exposing sensitive token data or API responses across different user sessions.

Root Cause Analysis

The root cause of CVE-2026-40155 lies in the caching strategy implemented within the AuthClientProvider class. In vulnerable versions (4.12.0 through 4.17.1), the SDK maintains a global dictionary named proxyFetchers. This structure caches stateful Fetcher instances using the target audience as the derivation key.

These cached Fetcher instances are not purely functional; they contain stateful logic responsible for executing HTTP requests, capturing session-specific data via closures, and managing the DPoP nonce retry sequence. When a proxy handler receives an incoming request, it retrieves the shared Fetcher instance corresponding to the audience and invokes it. This architecture violates thread-safety principles in asynchronous environments.

When a single fetcher handles concurrent requests, the internal state mutates unpredictably. If Request A triggers a 401 Unauthorized response with a new DPoP-Nonce, the shared fetcher updates its internal retry variables. Simultaneously, Request B entering the proxy handler retrieves the exact same fetcher object and attempts to execute its own DPoP negotiation using Request A's corrupted state.

This improper synchronization forces the shared fetcher to process mismatched closures. The asynchronous resolution of the DPoP retry sequence causes the token result or API response intended for Request A to be returned to Request B. The system lacks the isolation boundaries required to bind state mutations exclusively to the originating request context.

Code Analysis

The patch implemented in commit 98c36dc306970c2230ea1a32efef431d29b99978 fundamentally redesigns the proxy fetcher instantiation model. The vulnerable code initialized a global mapping of stateful objects directly within the authentication client class.

// VULNERABLE CODE (src/server/auth-client.ts)
private proxyFetchers: { [audience: string]: Fetcher<Response> } = {};
 
// ... inside the proxy handler ...
let fetcher = this.proxyFetchers[options.audience];
if (!fetcher) {
  fetcher = await this.fetcherFactory({ /* captured state */ });
  this.proxyFetchers[options.audience] = fetcher;
}

The code block above demonstrates how the proxyFetchers dictionary caches the fetcher instance. The fetcherFactory injects the getAccessToken closure, which contains session-specific parameters. Once cached, subsequent requests to the same audience reuse the fetcher, implicitly reusing the captured closures and state tracking variables meant for the initial request.

The remediation strategy eliminates the shared Fetcher instance entirely. Instead of caching the request-execution logic, the patched code caches only the DPoPHandle. This handle strictly represents the cryptographic signing identity, which is safe to persist across requests, rather than the request state itself.

// PATCHED CODE (src/server/auth-client.ts)
private proxyDpopHandles: { [audience: string]: oauth.DPoPHandle } = {};
 
// ... inside the proxy handler ...
const dpopHandle = this.useDPoP && this.dpopKeyPair
  ? (this.proxyDpopHandles[options.audience] ??= oauth.DPoP(
      this.clientMetadata,
      this.dpopKeyPair
    ))
  : undefined;
 
const fetcher = await this.fetcherFactory({
  useDPoP: this.useDPoP,
  fetch: this.fetch,
  getAccessToken,
  dpopHandle
});

By ensuring fetcherFactory is invoked during every proxy execution, the SDK generates a fresh, request-bound fetcher instance. The getAccessToken closure is now correctly scoped to the active HTTP request, resolving the concurrency defect and eliminating the potential for data cross-pollination.

Exploitation Mechanism

Exploitation of CVE-2026-40155 requires a narrow alignment of conditions within the target application. An attacker must manipulate the application into dispatching multiple concurrent requests to the affected proxy endpoints (/api/auth/me or /api/auth/my-org). Furthermore, the target application must have DPoP explicitly configured and active.

The attack leverages the inherent latency in the DPoP negotiation sequence. When an initial request is dispatched, the upstream Auth0 server returns a 401 Unauthorized challenge containing a DPoP-Nonce. This server round-trip creates an execution window. During this window, an attacker dispatches a secondary request to the identical proxy route.

Because Node.js processes asynchronous operations via the Event Loop, the secondary request accesses the shared Fetcher object while the primary request is suspended awaiting the retry response. The shared state is overwritten by the secondary request's context. Upon resumption, the primary request completes its execution utilizing the secondary request's closures.

The proof-of-concept for this vulnerability was established through the framework's internal integration tests. Test case 10.4 simulates this exact timing condition by dispatching parallel requests using distinct sessions, demonstrating that the vulnerable retry logic fails to keep the DPoP nonce strictly bound to the original session.

Impact Assessment

The security impact of CVE-2026-40155 is designated as Medium severity, carrying a CVSS v3.1 score of 5.4. The primary consequence of this vulnerability is the compromise of data confidentiality. When the race condition occurs, sensitive session identifiers, access tokens, or API response payloads belonging to one user can be improperly routed and disclosed to another concurrent user.

The attack complexity is assessed as High (AC:H). The execution of the exploit is heavily dependent on specific network timing, the presence of DPoP challenges, and the concurrent arrival of requests at the application tier. Reproducing the race condition reliably across wide-area networks poses a significant operational challenge for an attacker.

Privileges Required are Low (PR:L), as the attacker must possess a valid session to interact with the protected proxy endpoints. The integrity impact is categorized as Low (I:L), as the vulnerability does not allow direct manipulation of application state or persistent data modification. Availability is unaffected (A:N).

Current Exploit Prediction Scoring System (EPSS) data indicates a score of 0.0004, placing the vulnerability in the 12.12th percentile. This extremely low score reflects the highly specific preconditions required for exploitation. The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.

Remediation and Mitigation

The definitive remediation for CVE-2026-40155 is to upgrade the @auth0/nextjs-auth0 dependency to version 4.18.0 or later. This release comprehensively addresses the underlying architectural flaw by strictly scoping cryptographic handles and isolating fetcher logic to individual request lifecycles. Developers should verify the updated version within their package.json and lockfiles.

In environments where an immediate upgrade is structurally impossible, mitigation options are severely limited. The vulnerability is fundamentally tied to the interaction between the SDK's proxy handlers and the DPoP specification. Disabling DPoP would theoretically eliminate the attack vector, but this degrades the overall security posture by re-exposing the application to token theft and replay attacks.

Network detection of this vulnerability is highly complex due to the encrypted nature of the traffic and the application-layer context required. Security operations teams can monitor application logs for anomalous spikes in concurrent /me or /my-org endpoint access combined with an elevated rate of HTTP 401 responses. However, patching remains the only reliable defensive measure.

Official Patches

Auth0Official Fix Commit
Auth0Release v4.18.0

Fix Analysis (1)

Technical Appendix

CVSS Score
5.4/ 10
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:H/I:L/A:N
EPSS Probability
0.04%
Top 88% most exploited

Affected Systems

@auth0/nextjs-auth0 (Versions 4.12.0 through 4.17.1)

Affected Versions Detail

Product
Affected Versions
Fixed Version
@auth0/nextjs-auth0
Auth0
>= 4.12.0, <= 4.17.14.18.0
AttributeDetail
CWE IDCWE-362
Attack VectorNetwork
CVSS v3.1 Score5.4 (Medium)
EPSS Score0.0004 (12.12%)
Primary ImpactConfidentiality Loss (Cross-Session Data Exposure)
Exploit StatusProof of Concept (Integration Tests)
CISA KEVNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-362
Concurrent Execution using Shared Resource with Improper Synchronization

Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

Known Exploits & Detection

GitHub Security AdvisoryInformation regarding internal testing reproduction.

Vulnerability Timeline

Vulnerability reported (IBM X-Force Exchange)
2026-04-16
Fix commit (98c36dc) pushed to repository
2026-04-17
Version 4.18.0 released
2026-04-17
CVE-2026-40155 assigned and published
2026-04-17
GHSA-xq8m-7c5p-c2r6 published on GitHub
2026-04-21

References & Sources

  • [1]GitHub Security Advisory GHSA-xq8m-7c5p-c2r6
  • [2]NVD Record for CVE-2026-40155
  • [3]OSV Record for GHSA-xq8m-7c5p-c2r6

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.