9router

CVE-2026-49353

CVE-2026-49353 is a high-severity security vulnerability in 9router (npm), affecting versions <= 0.4.55. No fixed version is listed yet.

Key facts
CVSS score
7.5
High
Attack vector
Network
Issuing authority
GitHub Advisory Database
Affected package
9router
Fixed in
Not available
Disclosed
2026

Summary

Summary The fix for CVE-2026-46339 (unauthenticated RCE via unprotected MCP plugin routes) introduced a local-only access gate in src/dashboardGuard.js that restricts spawn-capable routes (/api/mcp/, /api/tunnel/, /api/cli-tools/) to loopback requests. The gate determines "local" by inspecting the Host and Origin HTTP headers rather than the TCP source address. When 9router is deployed behind a reverse proxy, tunnel (Cloudflare Tunnel, Tailscale, both natively supported), or is subject to DNS rebinding, these headers are attacker-controlled, allowing the local-only gate to be bypassed. A second factor (CLI token or JWT cookie) is required by canAccessLocalOnlyRoute(), but the CLI token is a deterministic HMAC of the machine ID (getConsistentMachineId), which is stable and predictable on cloud VMs. If the attacker can obtain or guess the machine ID (e.g., via another information disclosure, or on shared-tenant infrastructure), the full chain to MCP child process stdin injection is reachable. This is a variant / incomplete fix of CVE-2026-46339, the same attack surface (remote → MCP child process stdin) remains reachable under specific but realistic deployment configurations. Root Cause isLocalRequest() at src/dashboardGuard.js:93-101: This function trusts Host and Origin headers as proof of local origin. Both are attacker-controlled in any proxied deployment. The LOOPBACKHOSTS set (localhost, 127.0.0.1, ::1) is checked against these headers, not against the actual connection source IP. Attack Scenario Scenario 1: Cloudflare Tunnel / Tailscale Funnel 9router natively supports Cloudflare Tunnel and Tailscale (see LOCALONLYPATHS entries for /api/tunnel/). When exposed via tunnel: Attacker sends request to https://<tunnel-domain>/api/mcp/<plugin>/sse Sets Host: localhost:3000 and Origin: http://localhost:3000 isLocalRequest() returns true canAccessLocalOnlyRoute() then requires CLI token or (local + JWT) CLI token is getConsistentMachineId("9r-cli-auth"), a deterministic HMAC of the machine's hardware/OS identifiers Scenario 2: DNS Rebinding Attacker controls evil.com DNS, initially resolving to attacker IP Victim's browser navigates to evil.com (or via iframe/redirect) DNS rebinding switches evil.com → 127.0.0.1 Subsequent fetch to evil.com:3000/api/mcp/<plugin>/message reaches 9router Host header is evil.com:3000, this is blocked by the current check (not in LOOPBACKHOSTS) However, if the attacker uses localhost:3000 as the request host via CORS or service worker tricks, and the browser sends Host: localhost:3000, the gate opens Exploitation (when CLI token is obtained) Once past the gate, the attacker can: GET /api/mcp/<plugin>/sse, establish SSE session, get sessionId POST /api/mcp/<plugin>/message, send arbitrary JSON-RPC to the child process stdin The child process is one of: npx, node, python, python3, uvx, bunx, bun Depending on the MCP plugin implementation, this can achieve arbitrary code execution on the host Steps to Reproduce Deploy 9router behind a reverse proxy or tunnel From a remote host, send: Observe: SSE connection established, endpoint event received with message URL POST arbitrary JSON-RPC to the message endpoint Impact An attacker who can reach a proxied/tunneled 9router instance and obtain the deterministic CLI token can bypass the local-only restriction and interact with MCP child processes (node, python, npx, etc.) via stdin. This achieves the same impact as CVE-2026-46339: remote code execution on the host. The severity is reduced from CVE-2026-46339's CVSS 10.0 because: Requires proxied/tunneled deployment (not default localhost-only) Requires obtaining the CLI token (deterministic but not trivially guessable without another primitive) Remediation Check actual source IP, not headers. Use request.ip, request.socket.remoteAddress, or a trusted X-Forwarded-For header with known proxy configuration instead of Host/Origin for the local-only gate. Make CLI token non-deterministic. Generate a random token on first run and persist it, rather than deriving from machine ID. Machine IDs are often predictable or discoverable on cloud infrastructure. Bind MCP routes to loopback at the network layer. If MCP is local-only by design, the server should bind those routes to 127.0.0.1 only, not rely on middleware header checks. Credit: @snailsploit

Impact

Severity and exposure

CVE-2026-49353 has a CVSS score of 7.5 (High). The vector is network-reachable, no privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment.

No fixed version is listed yet, so configuration controls and monitoring matter more in the interim.

Affected versions

npm

  • 9router (<= 0.4.55)

Security releases

Not available
Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter instead of chasing every advisory.

Kodem's runtime-powered SCA identifies whether CVE-2026-49353 is reachable in your applications. Explore open-source security for your team.

See if CVE-2026-49353 is reachable in your applications. Get a demo

Already deployed Kodem? See CVE-2026-49353 in your environment

Remediation advice

No fixed version is listed for CVE-2026-49353 yet.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently asked questions about CVE-2026-49353

What is CVE-2026-49353?

CVE-2026-49353 is a high-severity security vulnerability in 9router (npm), affecting versions <= 0.4.55. No fixed version is listed yet.

How severe is CVE-2026-49353?

CVE-2026-49353 has a CVSS score of 7.5 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.

Which versions of 9router are affected by CVE-2026-49353?

9router (npm) versions <= 0.4.55 is affected.

Is there a fix for CVE-2026-49353?

No fixed version is listed for CVE-2026-49353 yet. Monitor the advisory for updates and apply mitigations in the interim.

Is CVE-2026-49353 exploitable, and should I be worried?

Whether CVE-2026-49353 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo

What actually determines whether CVE-2026-49353 is exploitable, and how bad it is?

Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.

Stop the waste.
Protect your environment with Kodem.