CVE-2026-52869 Overview
CVE-2026-52869 affects the MCP Python SDK (mcp on PyPI), a Python implementation of the Model Context Protocol (MCP). Versions prior to 1.27.2 route requests to existing sessions using only the session_id query parameter or Mcp-Session-Id header. The Server-Sent Events (SSE) transport mcp.server.sse.SseServerTransport and the stateful Streamable HTTP transport mcp.server.streamable_http_manager.StreamableHTTPSessionManager fail to verify the authenticated principal that created the session. A different bearer-token-authenticated client with a known session ID can inject JSON-RPC messages into another user's session. This flaw maps to [CWE-639: Authorization Bypass Through User-Controlled Key].
Critical Impact
Any bearer-token-authenticated client that obtains a valid session ID can hijack another user's MCP session and inject arbitrary JSON-RPC messages, breaking tenant isolation in multi-user MCP deployments.
Affected Products
- MCP Python SDK (mcp on PyPI) versions prior to 1.27.2
- Applications using mcp.server.sse.SseServerTransport (SSE transport)
- Applications using mcp.server.streamable_http_manager.StreamableHTTPSessionManager (stateful Streamable HTTP transport)
Discovery Timeline
- 2026-07-15 - CVE-2026-52869 published to the National Vulnerability Database
- 2026-07-16 - CVE-2026-52869 last updated in NVD
Technical Details for CVE-2026-52869
Vulnerability Analysis
The MCP Python SDK exposes two transport mechanisms that maintain server-side session state: SSE and stateful Streamable HTTP. Both transports identify the target session using a client-supplied session_id query parameter or Mcp-Session-Id header. The dispatch logic looks up the session object by identifier and forwards JSON-RPC messages into that session's message queue. The lookup never checks whether the currently authenticated principal matches the principal that established the session. As a result, authorization is decoupled from session ownership.
Root Cause
The bearer authentication middleware validates the token and populates request principal claims, but the transport layer treats the session ID as a sufficient routing key. Because bearer tokens on the affected code paths did not carry a sub (subject) claim tied to the session, the server had no reliable way to compare the caller identity against the session owner. This is a classic authorization bypass through a user-controlled identifier [CWE-639].
Attack Vector
An attacker who holds any valid bearer token accepted by the MCP server and who learns or guesses another user's session ID can send POST requests carrying arbitrary JSON-RPC payloads to that session. The injected messages are processed with the victim session's context, allowing the attacker to invoke tools, alter conversation state, or exfiltrate results streamed back to the legitimate client. Exploitation requires a valid token and knowledge of the session identifier, which is reflected in the elevated attack complexity but does not require user interaction.
# Security patch: bind transport sessions to the authenticated principal
# src/mcp/server/auth/middleware/bearer_auth.py
import json
import time
-from typing import Any
+from typing import Any, TypedDict
from pydantic import AnyHttpUrl
from starlette.authentication import AuthCredentials, AuthenticationBackend, SimpleUser
Source: GitHub Commit ce267b6
# Security patch: add subject and issuer claims to issued AccessTokens
# examples/servers/simple-auth/mcp_simple_auth/auth_server.py
"iat": int(time.time()),
"token_type": "Bearer",
"aud": access_token.resource, # RFC 8707 audience claim
+ "sub": access_token.subject, # RFC 7662 subject
+ "iss": str(server_settings.server_url),
}
)
Source: GitHub Commit 1abcca2
The fix propagates a subject field through the OAuth flow and binds each transport session to the authenticated principal, so subsequent lookups reject mismatched callers.
Detection Methods for CVE-2026-52869
Indicators of Compromise
- Multiple distinct bearer token subjects or client IP addresses posting to the same MCP session_id within a short interval.
- JSON-RPC requests to /messages or Streamable HTTP endpoints where the token principal differs from the principal recorded at session creation.
- Unexpected tool invocations or tools/call messages appearing in a session whose owner did not initiate the corresponding client action.
Detection Strategies
- Log the authenticated subject alongside every session lookup and alert when a session receives messages from more than one subject.
- Correlate MCP application logs with reverse proxy access logs to detect divergent source identities against a stable Mcp-Session-Id.
- Perform software composition analysis on Python dependencies to flag installations of mcp at versions below 1.27.2.
Monitoring Recommendations
- Instrument the MCP server to emit structured audit events containing session_id, subject claim, and client IP for every JSON-RPC dispatch.
- Alert on high-cardinality subject-to-session ratios in SIEM dashboards to surface hijacking attempts.
- Track anomalies in tool usage patterns per session, since injected messages often exercise different tools than the legitimate client.
How to Mitigate CVE-2026-52869
Immediate Actions Required
- Upgrade the mcp package to version 1.27.2 or later on every server exposing SSE or stateful Streamable HTTP transports.
- Rotate any bearer tokens or client credentials that could have been used to enumerate session identifiers during the exposure window.
- Terminate long-lived MCP sessions after the upgrade so that new sessions are bound to the authenticated principal under the fixed code path.
Patch Information
The issue is fixed in mcp version 1.27.2. See GitHub Release v1.27.2 and the GitHub Security Advisory GHSA-jpw9-pfvf-9f58. The remediation was delivered across Pull Request #2690, which adds sub and iss claims to issued access tokens, and Pull Request #2719, which binds transport sessions to the authenticated principal.
Workarounds
- Deploy a reverse proxy or middleware that extracts the bearer token subject and rejects requests where the subject does not match the principal recorded when the session was created.
- Restrict MCP servers to single-tenant deployments until the upgrade is applied, ensuring only one authenticated principal can reach a given process.
- Use high-entropy session identifiers and short session lifetimes to reduce the window in which a known session_id remains valid.
# Upgrade the MCP Python SDK to the fixed release
pip install --upgrade "mcp>=1.27.2"
# Verify the installed version
python -c "import mcp, importlib.metadata; print(importlib.metadata.version('mcp'))"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

