NewApp Monitoring is liveSign up free
AgentbeamBeta
AI agent vulnerability · MCP Python SDK

CVE-2026-52869: MCP Python SDK: HTTP transports serve session requests without verifying the authenticated principal

highCVSS 3.1 7.1GHSA-jpw9-pfvf-9f58

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 mcp

Clients 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.2

The 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

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 entries