1. Vulnerability Background
What is this vulnerability?
- CVE-2026-25536 is a session isolation flaw in the MCP TypeScript SDK.
- In affected versions, a single
McpServer/transport instance could be reused across multiple client connections in statelessStreamableHTTPServerTransportdeployments. - This reuse allowed response data, notifications, and request mapping state from one client session to leak into another.
Why is it critical/important?
- The MCP SDK is used to build server/client integrations for the Model Context Protocol.
- Failure of session isolation undermines confidentiality and integrity of model context exchanges.
- Cross-client contamination can expose data from one client to another, especially in multi-tenant or shared hosting environments.
Affected systems/versions:
- MCP TypeScript SDK versions 1.10.0 through 1.25.3.
- Patched in version 1.26.0.
- Most relevant for deployments using
StreamableHTTPServerTransportorWebStandardStreamableHTTPServerTransportin stateless mode.
2. Technical Details
Root cause analysis
- The core defect is improper transport/session reuse combined with persistent internal state.
StreamableHTTPServerTransportandWebStandardStreamableHTTPServerTransportmaintain request/stream mappings, message IDs, and in-flight request state.- When a transport instance is reused across independent HTTP requests without a session ID generator, internal maps and handlers are not reset.
McpServer.connect()also allowed reconnecting a protocol instance to a new transport without closing the previous connection.close()did not abort in-flight request handlers, allowing handlers from a closed session to continue sending messages.
Attack vector and exploitation conditions
- A vulnerable server exposes an MCP endpoint and constructs a global
McpServer/transport pair. - Multiple clients connect sequentially or concurrently to the same transport.
- In stateless mode (
sessionIdGeneratorundefined), the same transport object processes multiple HTTP requests. - This results in stale stream mappings, message ID collisions, and cross-session request routing.
Security implications
- Cross-session data leakage: one client may receive responses or notifications intended for another.
- Request misrouting: message IDs can collide, causing a request from one session to be interpreted as part of another.
- Information disclosure in shared hosting or multi-tenant environments.
- Potential denial of service or session confusion when transports are reused incorrectly.
3. Patch Analysis
What code changes were made?
- Example servers were updated to create a new
McpServerand transport per session/request instead of using a single long-lived instance.src/examples/server/standaloneSseWithGetStreamableHttp.tssrc/examples/server/honoWebStandardStreamableHttp.tssrc/examples/server/elicitationFormExample.tssrc/examples/server/ssePollingExample.ts
- Core transport logic was hardened.
src/server/webStandardStreamableHttp.tsadded_hasHandledRequestand rejects reuse of stateless transports after the first request.
- Protocol lifecycle handling was tightened.
src/shared/protocol.tsnow rejectsconnect()if already connected and aborts in-flight request handlers onclose().
- Tests were expanded to cover the behavior.
test/shared/protocol-transport-handling.test.tstest/integration-tests/stateManagementStreamableHttp.test.tstest/server/streamableHttp.test.ts
How do these changes fix the vulnerability?
- Ensuring per-session/per-request transport+server pairs removes shared mutable state between clients.
- The stateless transport guard enforces the intended contract: a transport without a session generator cannot be reused.
- Protocol
connect()guards prevent a single protocol instance from being attached to multiple transports. - Aborting in-flight handlers on close prevents stale handlers from emitting messages after a connection has ended.
Security improvements introduced
- Explicit fail-fast behavior for improper stateless transport reuse.
- Stronger connection lifecycle enforcement in protocol management.
- Example code now models safe patterns for stateless MCP deployments.
- Additional regression tests verify session isolation and transport handling.
4. Proof of Concept (PoC) Guide
Prerequisites for exploitation
- MCP TypeScript SDK version between 1.10.0 and 1.25.3.
- A server implementation exposing a stateless
StreamableHTTPServerTransportorWebStandardStreamableHTTPServerTransport. - Two client sessions or concurrent requests to the same transport.
Step-by-step exploitation approach
- Deploy a vulnerable server using a global
McpServerand transport.- Example:
const server = new McpServer(...); const transport = new StreamableHTTPServerTransport(); await server.connect(transport);
- Example:
- Have one client perform initialization and open a stream or send a request.
- Have a second client connect using the same endpoint and transport.
- Observe whether the second client receives messages from the first client or stale responses from the prior session.
Expected behavior vs exploited behavior
- Expected: each client session is isolated; session-specific messages remain confined to the originating client.
- Exploited: one client receives notifications or responses intended for another session; request/response IDs may be misassociated; stream mappings from previous sessions may be reused.
How to verify the vulnerability exists
- Run the vulnerable server example and connect two clients.
- In a stateless deployment, open two SSE streams or two WebStandard requests.
- If the same transport is reused, the second client should observe cross-session data or shared stream events.
- A robust verification is to compare the message IDs and session IDs returned by the transport; if they overlap or are reused across independent requests, the vulnerability is present.
5. Recommendations
Mitigation strategies
- Upgrade MCP TypeScript SDK to version 1.26.0 or later.
- For stateless endpoints, instantiate a fresh transport and
McpServerper request. - If you need shared sessions, use
sessionIdGeneratorto assign unique session IDs and avoid global reuse. - Do not reuse a
Protocolor transport object across multiple independent client connections.
Detection methods
- Look for errors from the new guard:
Stateless transport cannot be reused across requests. Create a new transport per request. - Monitor server logs for multiple
connect()calls on the same protocol instance withoutclose(). - Add regression tests that create multiple clients against stateless transports and verify isolation.
- Use request fuzzing or instrumentation to detect cross-session deliveries.
Best practices to prevent similar issues
- Treat transport objects as connection-scoped resources, not global singletons.
- Enforce explicit lifecycle management: connect, handle request, close.
- Implement per-session state separation in server frameworks.
- Add tests for session isolation and protocol reuse semantics.
- Avoid shared mutable state in protocols and transport layers when building stateless HTTP endpoints.
Summary
- CVE-2026-25536 is a legitimate cross-session isolation flaw in the MCP SDK.
- The patch fixes both the library and example usage patterns by enforcing per-request transports and stronger connection semantics.
- Upgrading to 1.26.0 and adopting proper session/transport handling is the correct remediation.