CVE-2026-25536

ADVISORY - github

Summary

Summary

Cross-client response data leak when a single McpServer/Server and transport instance is reused across multiple client connections, most commonly in stateless StreamableHTTPServerTransport deployments.

Impact

Who is affected: Any MCP server deployment using the TypeScript SDK where a single McpServer (or Server) instance is shared across multiple concurrent client connections. This is most likely in stateless mode (no sessionIdGenerator), where the natural but incorrect pattern is to create one server and transport and handle all requests through it. Stateful mode is also affected if the server instance is improperly shared across sessions, though this misconfiguration is less common since the stateful pattern naturally encourages per-session instances.

What happens: When two or more MCP clients send requests concurrently through a shared server instance, JSON-RPC message ID collisions cause responses to be routed to the wrong client's HTTP connection. Client A can receive response data intended for Client B, and vice versa, even when authorization was correctly enforced on each individual request.

The MCP SDK's client generates message IDs using a simple incrementing counter starting at 0. When two clients connect to the same server instance, they produce identical message IDs, causing the transport's internal request-to-stream mapping to overwrite one client's entry with another's — routing responses to the wrong HTTP connection.

Conditions for exploitation:

  • The server reuses a single McpServer/Server instance across requests or sessions (rather than creating fresh instances per request/session)
  • Two or more clients connect concurrently
  • Clients generate overlapping JSON-RPC message IDs (virtually guaranteed since the SDK's client uses an incrementing counter starting at 0)

Not affected:

  • Stateful servers that create a new McpServer + transport per session (the typical and recommended stateful pattern)
  • Stateless servers that create a new McpServer + transport per request
  • Single-client environments (e.g., local development with one IDE)

Patches

The fix adds runtime guards that turn silent data misrouting into immediate, actionable errors:

  1. Protocol.connect() now throws if the protocol is already connected to a transport, preventing silent transport overwriting across both stateful and stateless modes
  2. Stateless StreamableHTTPServerTransport.handleRequest() now throws if called more than once, enforcing one-request-per-transport in stateless mode

Servers that were incorrectly reusing instances will now receive a clear error message directing them to create separate instances per connection.

Workarounds

If projects cannot upgrade immediately, ensure the server creates fresh McpServer and transport instances for each request (stateless) or session (stateful):

// Stateless mode: create new server + transport per request
app.post('/mcp', async (req, res) => {
  const server = new McpServer({ name: 'my-server', version: '1.0.0' });
  // ... register tools, resources, etc.
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
  await server.connect(transport);
  await transport.handleRequest(req, res);
});

// Stateful mode: create new server + transport per session
const sessions = new Map();
app.post('/mcp', async (req, res) => {
  const sessionId = req.headers['mcp-session-id'];
  if (sessions.has(sessionId)) {
    await sessions.get(sessionId).transport.handleRequest(req, res);
  } else {
    const server = new McpServer({ name: 'my-server', version: '1.0.0' });
    // ... register tools, resources, etc.
    const transport = new StreamableHTTPServerTransport({
      sessionIdGenerator: () => randomUUID()
    });
    await server.connect(transport);
    sessions.set(transport.sessionId, { server, transport });
    await transport.handleRequest(req, res);
  }
});

Resources

Common Weakness Enumeration (CWE)

ADVISORY - nist

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

ADVISORY - github

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


NIST

CREATED

UPDATED

EXPLOITABILITY SCORE

2.8

EXPLOITS FOUND
-
COMMON WEAKNESS ENUMERATION (CWE)

CVSS SCORE

7.1high

GitHub

CREATED

UPDATED

EXPLOITABILITY SCORE

2.8

EXPLOITS FOUND
-
COMMON WEAKNESS ENUMERATION (CWE)

CVSS SCORE

7.1high