CVE-2026-23735: Silent Token Leakage via GraphQL Parallel Request Context Mix-Up

CVE: CVE-2026-23735
Product: graphql-modules (Node.js GraphQL framework)
Affected Versions: All releases between 2.2.1 up to 2.4.0 and 3.0.0 up to 3.1.0
Patched Versions: 2.4.1 and 3.1.1
Severity: High
CVSS: 8.7 (Network exploitable, no privileges required)
Exploitability: Easy to trigger — requires two parallel requests
Exploit Availability: Yes — proof-of-concept exists


Vulnerability Overview

In many GraphQL applications using graphql-modules, developers rely on dependency-injected providers that are created once per server instance (singleton). These providers sometimes need to access per-request data — like authentication tokens, user IDs, or session context — by using a mechanism called @ExecutionContext().

Under normal circumstances, each incoming GraphQL request has its own separate execution context. But in vulnerable versions of graphql-modules, the system that attaches this execution context to singleton providers is not synchronized properly. When two requests arrive at the same time and both invoke the same singleton provider that calls @ExecutionContext(), the context values can get mixed.

In simpler terms:

If two requests happen simultaneously, a provider may accidentally read the wrong request’s context, including auth tokens or session info.

This is not just theory — it has been reproduced reliably. When the library switches the execution context between requests, the token from one request can slip into the handler of another request.


How This Can Be Exploited

An attacker doesn’t need privileged access or special capabilities. Here’s a real exploitation scenario:

  1. The attacker targets an application that uses graphql-modules with vulnerable versions.
  2. They send two or more GraphQL requests at nearly the same time. These requests need to hit a code path where a singleton service uses @ExecutionContext().
  3. Due to the race, the context of request A gets mixed with request B.
  4. If request B carries a valid authentication token, and request A doesn’t (or has a different user), the application logic might accidentally process A with B’s credentials.

This can mean:

  • One user’s token being used to authorize another user’s action.
  • Sensitive authorization data leaking across requests.
  • Invalid or unexpected permission escalation.

The important point is that this isn’t a complex exploit — just uncoordinated timing from two parallel requests is enough.


Proof-of-Concept (PoC) (Educational)

A working proof-of-concept exists that demonstrates this issue. It does the following:

  1. It sets up two nearly simultaneous GraphQL requests.
  2. Both requests use a provider that calls @ExecutionContext() to read a request-specific value (for example, a unique header).
  3. Because the provider is shared (singleton), the values become interleaved.
  4. The PoC shows that instead of getting its own header value, the provider sometimes reads the other request’s value.

This PoC shows the exact context bleed and proves the vulnerability is real on unpatched versions.


Why This Happens

The root cause is shared state / improper synchronization:

  • Singleton services assume they can safely read the execution context at any time.
  • But if two async requests overlap, the internal mechanism that swaps context values does so incorrectly.
  • There is no strong isolation between concurrent request contexts in these versions.

This is a classic race condition where per-request data leaks because the library reuses a shared data path for request context.


How to Detect Vulnerable Code

Before patching, you want to know:

1) Check Your Dependencies

  • Look at your package.json, yarn.lock, pnpm-lock.yaml, or similar.
  • If graphql-modules appears in the affected ranges, you’re vulnerable.

Example:

[email protected]
[email protected]

These are unsafe — upgrade to 2.4.1 or 3.1.1 immediately.


2) Look for Code Using ExecutionContext In Singletons

Search for patterns like:

  • @ExecutionContext() inside services marked as singleton (default scope).
  • Providers that depend on authentication headers pulled from the execution context.

If these exist, they are likely impacted unless patched.


3) Runtime Behavior

At runtime, watch for these signs:

  • Backend APIs getting called with unexpected tokens.
    If your GraphQL layer talksto downstream services, look for logs where:
    • Request 1 triggers a downstream call with token A
    • Immediately after, another call appears with token B for the same trace
  • Audit logs showing mixed credentials
    A user may see actions logged under the wrong account.

Logging and Detection

Below are Splunk detection rules you can use to monitor for possible exploitation or symptoms. These are designed for typical GraphQL logs that include request IDs, timestamps, and auth token identifiers.


Splunk Detection Rules


Rule 1 — Same Operation, Multiple Tokens in Close Window

Detect if the same GraphQL operation sees more than one auth token within a tiny time window.

index=graphql_logs sourcetype=graphql
| stats dc(auth_token) as token_count values(auth_token) as tokens by operation_name, bin(_time, 1s)
| where token_count > 1
| table _time operation_name token_count tokens

If two different tokens were used for the same operation within one second, that may indicate context bleed.

Rule 2 — Token Flip Within Single Request

Flag when a single request ID sees different token contexts over its lifecycle.

index=graphql_logs sourcetype=graphql
| stats values(auth_token) as all_tokens by request_id
| where mvcount(all_tokens) > 1
| table request_id all_tokens

A single request claiming to have multiple tokens at different stages — a key sign of shared context going wrong.


Rule 3 — High Concurrency with Single Provider

If your logs tag providers or resolvers, check for providers handling overlapping requests with mismatched tokens.

index=graphql_logs sourcetype=graphql provider="AuthProvider"
| transaction provider request_id maxspan=5s
| stats dc(auth_token) as tokens_count by provider
| where tokens_count > 1
| table provider tokens_count

A provider getting requests with different tokens in a short window.


Immediate Mitigations

  • Avoid using @ExecutionContext() in singleton services.
    Only use it in request-scoped instances where the context is guaranteed unique.
  • Force request scoping.
    Convert providers that rely on request context so they are constructed fresh per request.
  • Add instrumentation.
    Log a quick fingerprint of the auth token at the start of each resolver to help trace anomalies.

Patching / Upgrade

The only full fix is to upgrade to the patched versions:

➡️ https://github.com/graphql-hive/graphql-modules/releases/tag/release-1768575025568
Update your graphql-modules package to 2.4.1 or 3.1.1 or higher and redeploy your services.

Doing this eliminates the race condition completely.


Final Takeaway

CVE-2026-23735 is a serious flaw in how graphql-modules handles per-request context in a concurrent environment. Because the library reused shared state between parallel requests, authentication tokens or user context could leak from one request into another. In real systems, that means one user’s token might be accidentally used to make decisions on behalf of a different user — even without any special privileges.

The good news is:
✔ The problem has a confirmed proof-of-concept.
✔ The fix is simple: upgrade to the patched versions.
✔ You can detect symptoms using logs and the Splunk rules above.

But until patched, systems using vulnerable versions are at risk whenever they receive concurrent GraphQL requests that hit services relying on request context.


Aegiron

Backed by 11+ years in cybersecurity and incident response, we decode the latest threats shaping today’s digital battlefield. This blog cuts through the noise with clear insights on vulnerabilities, emerging exploits, and the cyber news defenders can’t afford to miss.