CVE-2026-52869: MCP Python SDK: HTTP transports serve session requests without verifying the authenticated principal
The MCP Python SDK (`mcp` on PyPI) up to 1.27.1 routes SSE and Streamable HTTP requests to a session by session ID alone. An authenticated client that obtains another client's session ID can send JSON-RPC messages on that session. Servers using an HTTP transport with the built-in bearer-token authentication are affected. Upgrade to mcp 1.27.2.
Published Jul 16, 2026 · Analysis Oct 25, 2026
What an attacker can do
Both transports look up the session by identifier only: the session_id query parameter for mcp.server.sse.SseServerTransport, and the Mcp-Session-Id header for StreamableHTTPSessionManager. After the lookup, the request ran on that session without comparing its credentials to those of the client that created it. A request authenticated as a different OAuth client could therefore inject messages into someone else's session.
The exposure differs by transport. On SSE, the reply goes to the original client's event stream, so the attacker injects but cannot read the result. On Streamable HTTP, the reply comes back on the injecting request, so the attacker reads it as well. That can mean calling tools or reading resources with the victim's session state.
The bar is higher than the impact suggests. Session IDs are random UUIDs, so the attacker must get one out of band, for example from logs or by watching network traffic, and must hold a valid token of their own (PR:L, AC:H). Stdio servers, stateless Streamable HTTP and servers with no authentication are not affected. Servers where many users share one OAuth client are the most exposed to cross-user access.
Who is affected
PyPI package mcp 1.27.1 and earlier, for servers that use SSE or stateful Streamable HTTP together with the SDK's bearer-token authentication. SSE has been affected since the first release; Streamable HTTP since 1.8.0. Check the installed version:
pip show mcpClients of MCP servers are not affected by this flaw. It is a server-side issue in your own MCP server code.
mcp
- Ecosystem
- PyPI
- Affected
- <= 1.27.1
- Fixed in
- 1.27.2
- Check
pip show mcp
How to fix it
Upgrade to mcp 1.27.2:
pip install --upgrade mcp==1.27.2The fix records the authenticated principal that created each session (OAuth client ID plus the token's issuer and subject when supplied). A request from a different principal gets the same 404 as an unknown session.
If many end users share one OAuth client, make your token verifier fill AccessToken.subject, for example from the sub claim, so sessions are isolated per user. If you use a custom authentication backend instead of BearerAuthBackend, add an equivalent principal check yourself.
How to tell if you were hit
The advisory gives no log indicators. Look in your access logs for requests where the same Mcp-Session-Id or session_id value appears with different bearer tokens or client IDs. Also check whether session IDs are written to logs or visible to proxies, since that is the main way an attacker would obtain one. After upgrading, such cross-principal requests return 404. If AI agents connect to your server, a record of the agent's MCP tool calls helps show which calls came from an unexpected session; Beam records MCP tool calls on the agent side.
Original advisory
From the GitHub Advisory Database (CC BY 4.0).
Summary
In affected versions, the SSE and Streamable HTTP server transports routed incoming requests to an existing session based only on the session identifier, without verifying that the request was authenticated as the same principal that created the session. Anyone who learned or guessed a session ID could send JSON-RPC messages on that session, regardless of which bearer token the request carried.
Am I affected?
Only if a developer's application server uses an HTTP transport (SSE, or Streamable HTTP in stateful mode) and authenticates requests. Servers on stdio, stateless Streamable HTTP, or with no authentication configured are not affected.
Details
Both transports look up the target session by its identifier alone — the session_id query parameter for SSE (mcp.server.sse.SseServerTransport) and the Mcp-Session-Id header for Streamable HTTP (mcp.server.streamable_http_manager.StreamableHTTPSessionManager). Once the lookup succeeded, the request was handled on that session without comparing its authentication context to the credentials presented when the session was created, so a request authenticated as a different OAuth client could inject messages into the session. On the SSE transport the response is delivered to the original client's event stream; on the Streamable HTTP transport it is returned on the injecting request, so the injecting client can also read the result. The SSE transport has been affected since the first release; the Streamable HTTP transport since version 1.8.0.
Impact
Servers using either HTTP transport together with the SDK's built-in bearer-token authentication are affected: the per-client isolation that authentication provides can be bypassed for any session whose ID is known. Session IDs are randomly generated UUIDs, so exploitation requires obtaining one out of band (logs, network observation). Servers that do not enable bearer-token authentication have no per-client isolation to bypass and are not addressed by this advisory, and stateless Streamable HTTP deployments do not maintain sessions and are unaffected.
Mitigation
Upgrade to version 1.27.2 or later, which records the authenticated principal that created each session — the OAuth client ID together with the token's issuer and subject when the token verifier supplies them — and answers requests presenting a different principal with the same 404 response as for an unknown session.
Deployments where many end users share a single OAuth client (hosted MCP clients, gateways) should ensure their token verifier populates AccessToken.subject (e.g. from the token's sub claim) so sessions are isolated per user rather than per client. Deployments using a custom authentication backend other than the built-in BearerAuthBackend should enforce an equivalent check themselves.
Credited to srikanthramu, hewei-gikaku.
Questions
- Is a stdio MCP server affected by CVE-2026-52869?
No. Only the SSE and stateful Streamable HTTP transports are affected, and only when requests are authenticated. Stdio, stateless Streamable HTTP and unauthenticated servers are not.
- Can the attacker guess a session ID?
Not practically. Session IDs are random UUIDs, so the attacker needs to obtain one from logs or network observation. They also need a valid token for the same server.
- Does upgrading fully isolate users behind a shared OAuth client?
Only if your token verifier sets
AccessToken.subject. Without it, isolation is per OAuth client, not per user.
References
Read for this analysis:
- https://nvd.nist.gov/vuln/detail/CVE-2026-52869
- https://github.com/modelcontextprotocol/python-sdk/pull/2690
- https://github.com/modelcontextprotocol/python-sdk/pull/2719
- https://github.com/modelcontextprotocol/python-sdk/commit/1abcca2408a6b50e10ec601181f63f9978705c00
- https://github.com/modelcontextprotocol/python-sdk/commit/ce267b6fc515dc4efc1dc70b6975b16ff0feef0a
- https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.27.2
- https://github.com/advisories/GHSA-jpw9-pfvf-9f58
How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology
More MCP Python SDK vulnerabilities
All MCP Python SDK entriesCVE-2026-59951
MCP Python SDK: Unbounded Session Accumulation in StreamableHTTP Transport Enables Resource Exhaustion
medium7.5Oct 15, 2026CVE-2026-52870
MCP Python SDK: Experimental task handlers allow any client to access and cancel other clients' tasks
high7.6Jul 16, 2026CVE-2026-59950
MCP Python SDK: WebSocket server transport does not support Host/Origin validation
high7.6Jul 16, 2026CVE-2025-66416
Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection by default
high7.6Dec 2, 2025CVE-2025-53365
MCP Python SDK has Unhandled Exception in Streamable HTTP Transport, Leading to Denial of Service
high8.7Jul 4, 2025CVE-2025-53366
MCP Python SDK vulnerability in the FastMCP Server causes validation error, leading to DoS
high8.7Jul 4, 2025
