GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-RQFV-2MW9-78G2

Vulnerability from github – Published: 2026-09-11 20:35 – Updated: 2026-09-11 20:35
VLAI
Summary
MySQL MCP Server: Missing Origin/Host Validation in SSE Transport Enables Unauthenticated SQL Execution (DNS Rebinding / Direct Exposure)
Details

Summary

In SSE/HTTP transport mode, mysql_mcp_server constructs SseServerTransport without passing security_settings. As a result, the MCP Python SDK's DNS-rebinding protection (Origin/Host header validation) is disabled; the Starlette application has no CORS or TrustedHost middleware; and the service binds to 0.0.0.0 by default with no authentication on any route.

Trigger condition: MCP_TRANSPORT=sse. The default stdio mode is not affected.

Attack Scenarios

Scenario A — Direct exposure: Any network attacker can invoke execute_sql to run arbitrary SQL without credentials → full data dump, and via MySQL FILE privileges, arbitrary file read/write and RCE.

Scenario B — DNS rebinding (local bind): An attacker lures a victim's browser to a malicious page, rebinds their domain to 127.0.0.1, and uses the browser as a proxy to invoke execute_sql as same-origin.

Root Cause

In src/mysql_mcp_server/server.py:

  1. SseServerTransport is constructed without security_settings — the SDK defaults enable_dns_rebinding_protection to False.
  2. The Starlette app has no CORS or TrustedHost middleware.
  3. All three routes (/, /sse, /messages/) are unauthenticated.
  4. The service binds to 0.0.0.0 by default.
  5. The sink is cursor.execute(query) with a fully attacker-controlled query.

Impact

  • Unauthenticated arbitrary SQL execution against the configured database
  • Full data exfiltration and modification
  • If the MySQL account holds FILE privilege: arbitrary file read (LOAD_FILE) and write (INTO OUTFILE) — potential RCE via webshell drop
  • Internet-wide scanning has identified 25 publicly reachable SSE instances of this project

Fix

Released in v0.4.2: DNS-rebinding protection is now enabled by passing TransportSecuritySettings(enable_dns_rebinding_protection=True) to SseServerTransport, and the documented recommended bind address is 127.0.0.1.

Credits

Discovered by Huanchen, SongWu (JHU), and BrookeYangRui (JHU).

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "mysql-mcp-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.4.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59971"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-306",
      "CWE-346"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-11T20:35:42Z",
    "nvd_published_at": null,
    "severity": "CRITICAL"
  },
  "details": "## Summary\n\nIn SSE/HTTP transport mode, `mysql_mcp_server` constructs `SseServerTransport` without passing `security_settings`. As a result, the MCP Python SDK\u0027s DNS-rebinding protection (Origin/Host header validation) is disabled; the Starlette application has no CORS or TrustedHost middleware; and the service binds to `0.0.0.0` by default with no authentication on any route.\n\n**Trigger condition:** `MCP_TRANSPORT=sse`. The default stdio mode is not affected.\n\n## Attack Scenarios\n\n**Scenario A \u2014 Direct exposure:** Any network attacker can invoke `execute_sql` to run arbitrary SQL without credentials \u2192 full data dump, and via MySQL `FILE` privileges, arbitrary file read/write and RCE.\n\n**Scenario B \u2014 DNS rebinding (local bind):** An attacker lures a victim\u0027s browser to a malicious page, rebinds their domain to `127.0.0.1`, and uses the browser as a proxy to invoke `execute_sql` as same-origin.\n\n## Root Cause\n\nIn `src/mysql_mcp_server/server.py`:\n\n1. `SseServerTransport` is constructed without `security_settings` \u2014 the SDK defaults `enable_dns_rebinding_protection` to `False`.\n2. The Starlette app has no CORS or TrustedHost middleware.\n3. All three routes (`/`, `/sse`, `/messages/`) are unauthenticated.\n4. The service binds to `0.0.0.0` by default.\n5. The sink is `cursor.execute(query)` with a fully attacker-controlled query.\n\n## Impact\n\n- Unauthenticated arbitrary SQL execution against the configured database\n- Full data exfiltration and modification\n- If the MySQL account holds `FILE` privilege: arbitrary file read (`LOAD_FILE`) and write (`INTO OUTFILE`) \u2014 potential RCE via webshell drop\n- Internet-wide scanning has identified 25 publicly reachable SSE instances of this project\n\n## Fix\n\nReleased in v0.4.2: DNS-rebinding protection is now enabled by passing `TransportSecuritySettings(enable_dns_rebinding_protection=True)` to `SseServerTransport`, and the documented recommended bind address is `127.0.0.1`.\n\n## Credits\n\nDiscovered by Huanchen, SongWu (JHU), and BrookeYangRui (JHU).",
  "id": "GHSA-rqfv-2mw9-78g2",
  "modified": "2026-09-11T20:35:42Z",
  "published": "2026-09-11T20:35:42Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/designcomputer/mysql_mcp_server/security/advisories/GHSA-rqfv-2mw9-78g2"
    },
    {
      "type": "WEB",
      "url": "https://github.com/designcomputer/mysql_mcp_server/issues/92"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/designcomputer/mysql_mcp_server"
    },
    {
      "type": "WEB",
      "url": "https://github.com/designcomputer/mysql_mcp_server/releases/tag/v0.4.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "MySQL MCP Server: Missing Origin/Host Validation in SSE Transport Enables Unauthenticated SQL Execution (DNS Rebinding / Direct Exposure)"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…