🌏 中文版
Summary
MoLing is a dependency-free, locally-run MCP server written in Go that bills itself as a personal office assistant: it reads and writes files, runs shell commands, and drives a browser, all through direct OS APIs. Security researchers Songwu, Zeyu Luo, Dr. CAO Yinfeng, and Kevin found that when a user starts MoLing in SSE (Server-Sent Events) mode with the -l flag, its /sse and /message HTTP endpoints accept requests from anyone — no authentication at all — and the underlying mcp-go library adds Access-Control-Allow-Origin: * to every response, tearing down the browser's same-origin protections in the process. If the victim simply visits a malicious page while MoLing is running, that page can silently grab a one-time sessionId and use it to issue arbitrary MCP tool calls. GitHub assigned CVE-2026-62863, rated 9.6 Critical on CVSS 3.1.
Key facts
| Field | Value |
|---|---|
| Incident type | Privilege Escalation / Session Hijack (missing auth + CORS misconfiguration in an MCP server) |
| Scope | gojue/moling versions before 0.5.0, run with the -l (SSE mode) flag |
| Severity | Critical (CVSS 3.1 9.6, AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L) |
| CVE | CVE-2026-62863 (CWE-306 missing authentication, CWE-942 overly permissive cross-domain policy) |
| Sources | GitHub Security Advisory GHSA-qpgh-hp5g-4vwp, OpenCVE, TheHackerWire |
Attack surface
The entire attack happens inside the victim's own browser — the attacker never has to touch the victim's machine directly. The victim starts MoLing in SSE mode (moling -l 127.0.0.1:6789), then browses to a page the attacker controls (or one that's been compromised to serve malicious script). That page quietly opens new EventSource('http://127.0.0.1:6789/sse') in the background. Because MoLing's response carries Access-Control-Allow-Origin: *, the browser lets the cross-origin page read a connection it should have blocked under the same-origin policy. MoLing broadcasts a sessionId over the endpoint event when the connection opens; the attacker's page reads that value and immediately replays it against /message?sessionId=<stolen value>, impersonating the victim to call whatever MCP tools are configured — file I/O, shell execution, or browser automation.
- Malicious page opens a cross-origin EventSource connection to MoLing
- MoLing's wildcard CORS lets the read through; the sessionId leaks to the page
- The page replays the stolen sessionId against the /message tool endpoint
- MoLing executes the tool call and returns the result to the page
Precondition — the victim already started MoLing in SSE mode with -l, and has the malicious page open in a browser tab
Two problems stack on top of each other here. First, /sse and /message have no authentication mechanism at all (CWE-306, missing authentication for a critical function). Second, the mcp-go library hardcodes Access-Control-Allow-Origin: * on SSE responses (CWE-942, overly permissive cross-domain policy), which strips away the browser-side defense that would otherwise have blocked cross-site reads. GitHub's advisory flags a common wrong assumption here: binding the listener to 127.0.0.1 doesn't help, because the connection is initiated by the victim's own browser from localhost — loopback binding is irrelevant to whether this attack works.
This maps to OWASP LLM06, Excessive Agency: once an MCP tool is granted filesystem and command-execution capability, anyone who can impersonate the session gets the same privileges, and MoLing's auth layer never separated "who can call a tool" from "what the tool is allowed to do." Zoom out, and it's also another case of a downstream project inheriting a dangerous default (wildcard CORS) straight from an upstream library — the same systemic gap that recent MCP ecosystem surveys have flagged, with one finding 91.8% of tested public servers running with no OAuth at all.
Defense
Do now
- Upgrade
gojue/molingto v0.5.0 or later. The new version addssseSecurityMiddleware, which requires every request to carryAuthorization: Bearer <token>or a?token=query parameter, checked withcrypto/subtle.ConstantTimeCompareto avoid timing attacks - If you can't upgrade yet: don't run MoLing with
-l(SSE mode) on a machine that might browse untrusted sites, and consider pausing SSE exposure entirely in the meantime - Audit every MCP server you run over SSE/HTTP for the same
Access-Control-Allow-Origin: *response header — this isn't unique to MoLing, it's a default baked into themcp-golibrary that any project built on it should re-check
Longer term
- MCP server auth shouldn't depend on an assumption about what sites the user might browse. Any MCP server that accepts HTTP/SSE connections should require a token or stronger auth by default, not bolt it on after a disclosure
- Apply least-privilege scoping to MCP tools that can touch the filesystem or run commands, so a single hijacked session doesn't translate into full host access
- Add routine MCP server scanning to your pipeline — Snyk's Agent Scan (formerly Invariant Labs) and Cisco's mcp-scanner both check for tool poisoning, over-broad permissions, and SSRF; CORS misconfiguration belongs in that same routine-audit bucket
Impact
No public PoC has shown up in open research repositories yet, and both TheHackerWire and CISA's enrichment list it as unexploited in the wild, with an EPSS score under 1% — this is still at the disclosure stage, not an active-attack stage. But the attack complexity is low (no privileges required, just a browser visit), and because MoLing is specifically a local office-assistant tool with filesystem and command-execution capability, a single visit to the wrong page can mean local files leaked or arbitrary commands run.
If your agent stack runs any MCP server over HTTP/SSE, treat this as a prompt to go check: look for Access-Control-Allow-Origin: * in the response headers, confirm there's an enforced auth layer, and don't assume "only bound to localhost" means safe.
Takeaway
I'd always treated "bound to 127.0.0.1" as the last line of defense for a local service — this is the first time it clicked that when the attack rides in through the victim's own browser, that line does nothing at all, because the browser is already standing on the localhost side of the fence. The CORS header is the actual switch that decides who gets to read the response. Worth remembering when auditing local MCP servers: "is a port exposed" and "is CORS configured correctly" are two separate questions, not one.
References
- GitHub Security Advisory GHSA-qpgh-hp5g-4vwp — MoLing SSE auth bypass and CORS wildcard
- CVE-2026-62863 — OpenCVE full record (CVSS, CWE, fixed version)
- CVE-2026-62863: MoLing MCP Server Unauthenticated Cross-Origin Session Hijack to Arbitrary Command Execution — TheHackerWire
- Fix PR #48 (adds token auth and CORS-stripping middleware)
- v0.5.0 release notes
- gojue/moling project page
- Snyk Agent Scan (formerly Invariant Labs' mcp-scan)
- Cisco mcp-scanner