CVE-2025-27097 - Variable Caching Flaw in GraphQL Mesh Federation Gateway Leads to Memory Leak and Token Replay

Published: June 2024

TL;DR

A security vulnerability in GraphQL Mesh (CVE-2025-27097) affects applications using GraphQL Mesh as a federation gateway. When using transforms at the root or source level, variables from the first query sent are reused for identical queries—even if new variables are later supplied. This means sensitive information, such as authentication tokens sent via variables, can be inadvertently reused on subsequent requests, leading to accidental token replay and a short-lived memory leak.

What is GraphQL Mesh?

GraphQL Mesh is an all-in-one gateway and federation framework for working with various sources—including traditional GraphQL subgraphs, REST APIs, gRPC endpoints, and SQL or NoSQL databases like MySQL, PostgreSQL, and MongoDB.

Developers use Mesh to:

Combine GraphQL and non-GraphQL services into a single graph API.

- Add transforms to modify resolvers, queries, or schemas for security, performance, or compatibility.

Description

When a transform is used at the root level or for a specific data source, GraphQL Mesh incorrectly caches not only the parsed query but also the variables from the initial request. If another client submits the *same query string* but with *different variables*, Mesh continues to use the variables from the original query—until the internal cache (an LRU, or Least Recently Used, mechanism) evicts the entry.

If a token or sensitive information is sent as a variable in a query, the next clients using the same query string may “inherit” the original token, even if they send a different token. This can lead to authentication problems and temporary memory leaks.

Impact

- Short-term memory leak: The cache stores variables for each unique query string until the cache size limit is reached and entries are evicted.
- Token replay: If a token is passed in the variable and a second user reuses the same query string, their request may be processed with the previous user's token.

> Note: The impact is *bounded*; the leak does not grow with every request but with each unique operation (i.e., query shape) until LRU cache eviction.

A GraphQL Mesh gateway uses transforms and supports this mutation

mutation Login($token: String!) {
  user(data: $token) {
    id
    name
  }
}

First client sends:

{
  "query": "mutation Login($token: String!) { user(data: $token) { id name } }",
  "variables": { "token": "FIRST_USER_SECRET_TOKEN" }
}

Second client (shortly after) sends

{
  "query": "mutation Login($token: String!) { user(data: $token) { id name } }",
  "variables": { "token": "SECOND_USER_TOKEN" }
}

Due to CVE-2025-27097

- The Mesh DocumentNode cache will reuse the variables from the *first* request (FIRST_USER_SECRET_TOKEN) for the *second* request, ignoring the new SECOND_USER_TOKEN.

Here’s a simplified sketch, not the actual Mesh code, but enough to show the bug

// Imagine mesh uses this LRU cache per operation:
const cache = new Map();

function executeOperation(request) {
  const opKey = request.query; // Just the GraphQL query string
  let docNode = cache.get(opKey);

  if (!docNode) {
    docNode = {
      parsedDoc: parseGraphQL(request.query),
      cachedVars: request.variables // <-- DANGER: Caches the first variables
    };
    cache.set(opKey, docNode);
  }
  
  // On following requests: ignores incoming variables!
  return resolve(docNode.parsedDoc, docNode.cachedVars);
}

Correct behavior would be to parse/save the DocumentNode but not the variables, always using the current incoming request variables.

Exploitation Details

1. Attacker/Client A sends a query with their own authentication token in the variable.

Client B sends the same query string, but with their own (or a completely invalid) token.

3. Gateway executes Client B’s request using Client A’s token, possibly exposing data or allowing unauthorized access depending on internal business logic.

Timing window: The bug only applies until the LRU cache evicts the “document” (query), which may be thousands of requests later.


## References / Further Reading

- GraphQL Mesh homepage
- Official advisory and patch (replace with actual GHSA when available)
- Understanding the LRU cache)

Do not pass tokens via variables: Prefer using HTTP headers for authentication.

- Purge LRU cache aggressively on user/session change.

Conclusion

CVE-2025-27097 in GraphQL Mesh highlights how variable misuse in caching logic can lead to inadvertent replay of sensitive information between sessions. While the memory footprint is limited, the security impact—especially around auth tokens or session data—is significant. Upgrade your dependencies and audit your use of GraphQL variables in the gateway immediately.


*If you’re running GraphQL Mesh at the gateway of your microservices or federated GraphQL stack, check your version and update now!*

Timeline

Published on: 02/20/2025 21:15:26 UTC
Last modified on: 02/27/2025 20:27:24 UTC