Nhost Local MCP Server Unauthenticated CORS Bypass Leading to Full Project Takeover (CVE-2026-34200)
by skoveit (Anas) · 2026-07-05
- Severity
- Critical
- CVE
- CVE-2026-34200 (GHSA-6c5x-3h35-vvw2)
- Category
- web
- Affected product
- Nhost CLI local MCP server (nhost mcp start)
- Affected versions
- Versions of the Nhost CLI using the vulnerable mcp-go-based local MCP server (see GHSA-6c5x-3h35-vvw2)
- Disclosed
- 2026-07-05
- Patch status
- unpatched
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-03 |
| Author / Researcher | skoveit (Anas) |
| CVE / Advisory | CVE-2026-34200 (GHSA-6c5x-3h35-vvw2) |
| Category | web |
| Severity | Critical |
| CVSS Score | 9.6 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H) |
| Status | PoC |
| Tags | mcp, cors, csrf, drive-by, cors-bypass, credential-theft, hasura, dns-rebinding |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Nhost CLI local MCP server (nhost mcp start) |
| Versions Affected | Versions of the Nhost CLI using the vulnerable mcp-go-based local MCP server (see GHSA-6c5x-3h35-vvw2) |
| Language / Platform | Go-based local server listening on localhost (default :8080); PoC written in HTML/JavaScript |
| Authentication Required | No (inbound requests to the local MCP server) |
| Network Access Required | No — exploited via a victim’s browser visiting an attacker-controlled web page while the MCP server is running locally |
Summary
The Nhost CLI’s local MCP server, used to let AI agents/tools manage a developer’s Nhost project, has no inbound authentication and inherits a permissive Access-Control-Allow-Origin: * CORS policy from the underlying mcp-go library. Because the server does not strictly validate the Content-Type header on its JSON-RPC message endpoint, an attacker-controlled web page can send a Content-Type: text/plain POST request that qualifies as a CORS “simple request,” letting the browser skip the preflight OPTIONS check entirely. A malicious page can first open a cross-origin EventSource connection to the server’s /sse endpoint to capture a live session ID, then POST an MCP tools/call request (e.g. graphql-query or manage-graphql) using that session, since the server holds the developer’s actual Admin Secret/PAT and attaches it to outbound requests on the caller’s behalf. The included PoC is a self-contained HTML/JS page that, when opened by a victim with the MCP server running, silently connects to http://127.0.0.1:8080/sse, steals the session endpoint, and issues a list_sessions_and_beacons tool call to demonstrate data exfiltration.
Vulnerability Details
Root Cause
The local MCP server combines a hardcoded wildcard CORS policy (Access-Control-Allow-Origin: *) with a lack of Content-Type enforcement on its JSON-RPC endpoint, allowing cross-origin “simple requests” to bypass the browser’s CORS preflight; combined with zero inbound authentication, any page the victim visits can issue arbitrary MCP tool calls carrying the developer’s privileged Admin Secret/PAT.
Attack Vector
- Victim developer runs
nhost mcp start(or equivalent), starting the local MCP server onlocalhost:8080(or0.0.0.0in shared-access configurations). - Victim visits an attacker-controlled web page while the MCP server is active.
- The page opens a cross-origin
EventSourcetohttp://127.0.0.1:8080/sse; the browser allows this because of the wildcard CORS header, and the page captures the session’sendpointevent containing a session ID. - The page issues a
fetch()POST withmode: "no-cors"andContent-Type: text/plainto the captured endpoint, carrying a JSON-RPCtools/callpayload (e.g.graphql-query,manage-graphql); this qualifies as a CORS simple request and bypasses preflight. - The MCP server executes the tool call using the developer’s locally configured Admin Secret/PAT and streams the result back over the same SSE connection, which the malicious page reads to exfiltrate data.
Impact
Complete compromise of the developer’s Nhost project(s): exfiltration of production database contents, arbitrary SQL migrations/table drops via Hasura metadata management, rewriting of Hasura permissions, and hijacking of the developer’s Cloud PAT/Admin Secret — all from a single, silent page visit with no further user interaction.
Environment / Lab Setup
Target: Nhost CLI local MCP server (nhost mcp start --bind localhost:8080), configured with a project
Attacker: Any web browser reachable by the victim; a hosted HTML/JS page (exploit.ts) served from any origin
Proof of Concept
PoC Script
See
exploit.tsin this folder.
| |
Despite the .ts extension, the file is a self-contained HTML/JavaScript page: it opens an EventSource to the victim’s local MCP server, captures the session endpoint from the endpoint SSE event, and sends a crafted text/plain JSON-RPC POST request invoking the list_sessions_and_beacons MCP tool, displaying any exfiltrated data returned over the SSE stream in the page’s log/output panel.
Detection & Indicators of Compromise
Signs of compromise:
- Requests to the local MCP server’s
/sseor/messageendpoints originating from browser tabs/pages not belonging to the Nhost tooling itself - MCP tool-call logs showing
graphql-queryormanage-graphqlinvocations correlated with a browser session rather than a CLI/IDE integration - Unexpected Hasura metadata changes or SQL migrations shortly after a developer browsed to an unfamiliar site while
nhost mcp startwas running
Remediation
| Action | Detail |
|---|---|
| Primary fix | Apply the vendor fix referenced in GHSA-6c5x-3h35-vvw2 (require a generated bearer token for all inbound local MCP requests) once available for the installed CLI version |
| Interim mitigation | Only run nhost mcp start when actively needed and avoid browsing untrusted sites while it is running; bind the server to loopback only (never 0.0.0.0); reject requests without a strict Content-Type: application/json; ask upstream mcp-go maintainers to drop the wildcard CORS origin |
References
Notes
Mirrored from https://github.com/skoveit/CVE-2026-34200 on 2026-07-05.