Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-52869

CVE-2026-52869: MCP Python SDK Auth Bypass Vulnerability

CVE-2026-52869 is an authentication bypass flaw in MCP Python SDK that allows authenticated clients to hijack sessions and inject JSON-RPC messages. This article covers technical details, affected versions, and mitigations.

Published:

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.

python
# 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

python
# 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.
bash
# 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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.