MySQL MCP Server: Missing Origin/Host Validation in SSE Transport Enables Unauthenticated SQL Execution
A MySQL tool that lets AI assistants query databases can be run without any password check. If someone turns on its network mode, anyone on that network can read, change, or delete data in the connected database.
- Severity
- CriticalCVSS 3.1 · 10.0 · github.com
- Fix
- Fixed in 0.4.2
- Affected versions
- before 0.4.2
- Weakness
- CWE-306Missing Authentication for Critical Function
- Affects
- mysql-mcp-server
How it works
- The MySQL MCP Server lets AI tools send database queries through a small helper program.
- When that helper runs in its network-facing SSE mode, it builds its connection handler without turning on the check that confirms a request is really coming from a trusted address.
- The web app behind it adds no login requirement to any of its three routes and listens on every network interface by default.
- Because of this, anyone who can reach the service can send it a command that runs a SQL query with no credentials at all.
- The default stdio mode does not have this problem, only SSE mode does.
What to do
Run python3 -m pip show mysql-mcp-server to see the installed version, and compare it against 0.4.2. Check whether you deployed it with MCP_TRANSPORT=sse rather than the default stdio mode, since only SSE mode is exposed. If your version is 0.4.1 or earlier and SSE mode is enabled, treat any server it can reach as exposed.
Run this in the application environment you want to check:
python3 -m pip show mysql-mcp-serverUpdate to mysql-mcp-server 0.4.2 or later with python3 -m pip install -U mysql-mcp-server, which turns on Origin/Host validation by default. Set MCP_SSE_HOST to 127.0.0.1 instead of the default 0.0.0.0 so the service does not listen on every network interface. If you must expose it beyond localhost, use the MCP_SSE_ALLOWED_HOSTS setting to list only trusted hosts.
Technical details
Affected software: mysql-mcp-server
mysql_mcp_server builds its SseServerTransport without passing security_settings, so the MCP Python SDK's enable_dns_rebinding_protection stays at its default of False. The Starlette app adds no CORS or TrustedHost middleware, all three routes (/, /sse, /messages/) require no authentication, and MCP_SSE_HOST defaults to 0.0.0.0. This lets a remote, unauthenticated caller invoke the execute_sql tool directly. Version 0.4.2 fixes this by passing TransportSecuritySettings(enable_dns_rebinding_protection=True) with default allowed hosts of localhost and 127.0.0.1, extendable via MCP_SSE_ALLOWED_HOSTS.
Severity breakdown
- Attack vector Network Requires network access to the vulnerable service
- Attack complexity Low Low complexity under the assessed conditions
- Privileges required None Attacker needs no account or login
- User interaction None No victim action needed
- Scope Changed Impact crosses a security authority boundary
- Confidentiality impact High Sensitive data can be exposed with serious impact
- Integrity impact High Protected data can be changed with serious impact
- Availability impact High The service can stop or suffer serious disruption
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H Open in FIRST.org calculatorReferences
- github.com · v0.4.2 (tag) vendor advisory patch release notes
- github.com · GHSA-rqfv-2mw9-78g2 vendor advisory
- github.com · issue #92 vendor advisory GitHub Advisory
- osv.dev · CVE-2026-59971 vdb entry