Skip to main content
Vulnerability Database/CVE-2026-56681

CVE-2026-56681: 9Router Authentication Bypass Vulnerability

CVE-2026-56681 is an authentication bypass flaw in 9Router that allows remote attackers to spoof local requests and access API endpoints without authentication. This post covers technical details, affected versions, and mitigation.

Published:

CVE-2026-56681 Overview

CVE-2026-56681 is an authentication bypass vulnerability in 9Router, an AI router and token-saving proxy. Versions prior to 0.5.6 trust the client-supplied X-9r-Real-Ip header in src/dashboardGuard.js when the sanitizing custom-server.js wrapper is bypassed. A remote unauthenticated attacker can set this header to 127.0.0.1 and be classified as a local client, satisfying the isLocalRequest check that allows canAccessPublicLlmApi to skip API-key validation on /api/v1/* routes. Successful exploitation grants unauthorized use of the instance owner's configured Large Language Model (LLM) providers, consumption of paid credits, and enumeration of configured providers and models via GET /api/v1/models.

Critical Impact

Unauthenticated remote attackers can spoof loopback identity to abuse configured LLM providers, drain paid credits, and enumerate provider inventory.

Affected Products

  • 9Router versions prior to 0.5.6
  • Deployments exposing Next.js without the sanitizing custom-server.js wrapper
  • Instances routing /api/v1/* requests through the affected dashboardGuard.js logic

Discovery Timeline

  • 2026-09-22 - CVE-2026-56681 published to the National Vulnerability Database (NVD)
  • 2026-09-22 - Last updated in NVD database

Technical Details for CVE-2026-56681

Vulnerability Analysis

The flaw is a reliance-on-untrusted-input weakness [CWE-807] in the request-origin classification logic. 9Router's dashboardGuard.js consults isLocalRequest to decide whether canAccessPublicLlmApi should skip API-key validation. In deployments where requests do not first traverse the sanitizing custom-server.js wrapper, the X-9r-Real-Ip header remains client-controlled when it reaches Next.js.

An attacker sends any request with the header X-9r-Real-Ip: 127.0.0.1. The guard treats the caller as loopback and bypasses authentication. The verified GET /api/v1/models route is confirmed exploitable, exposing the provider and model inventory, and downstream LLM proxy endpoints become abusable without credentials.

Root Cause

The root cause is that dashboardGuard.js trusts a forwarding header without verifying that the TCP peer is a trusted reverse proxy. The custom-server.js wrapper was intended to strip and rewrite X-9r-Real-Ip, X-Forwarded-For, and X-9r-Via-Proxy before Next.js sees them. When Next.js is reached directly, that sanitization never runs, allowing header injection to spoof loopback identity.

Attack Vector

Exploitation requires only network reachability to the 9Router HTTP interface and no prior authentication or user interaction. The attacker issues a single HTTP request against /api/v1/models or another /api/v1/* route with the spoofed header. Because the guard skips API-key validation, downstream calls consume the instance owner's configured LLM provider credits.

javascript
// Patch from custom-server.js (v0.5.6) — anchors trust to the TCP peer
const socketIp = req.socket && req.socket.remoteAddress ? req.socket.remoteAddress : "";
const xff = req.headers["x-forwarded-for"];
const xRealIp = req.headers["x-real-ip"];
const viaProxy = !!(xff || xRealIp);
const isLoopbackProxy =
  socketIp === "127.0.0.1" ||
  socketIp === "::1" ||
  socketIp === "::ffff:127.0.0.1";
// Trust forwarding headers only when the TCP peer is a local reverse proxy.
// Direct/public sockets remain keyed by the unspoofable peer address.
const proxyIp = xRealIp || (xff ? String(xff).split(",")[0].trim() : "");
const ip = isLoopbackProxy && proxyIp ? proxyIp : socketIp;
delete req.headers["x-9r-real-ip"];
delete req.headers["x-forwarded-for"];
delete req.headers["x-9r-via-proxy"];

Source: GitHub commit efd20be

Detect Identity Attacks the Moment Authentication Fails

Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.

Stop Identity Attacks

Detection Methods for CVE-2026-56681

Indicators of Compromise

  • Inbound HTTP requests carrying an X-9r-Real-Ip header set to 127.0.0.1, ::1, or ::ffff:127.0.0.1 from a non-proxy source address.
  • Unexpected GET /api/v1/models responses served without an accompanying API key.
  • Sudden spikes in outbound calls or paid-credit consumption against configured LLM providers.
  • /api/v1/* traffic from client IPs that do not correspond to the deployment's trusted reverse-proxy tier.

Detection Strategies

  • Log every request header value for X-9r-Real-Ip, X-Forwarded-For, and X-9r-Via-Proxy alongside the raw TCP peer address, and alert on mismatches.
  • Compare req.socket.remoteAddress against the effective classified IP; flag any case where an untrusted peer yields a loopback classification.
  • Baseline normal usage of /api/v1/models and downstream LLM proxy routes, then alert on unauthenticated access patterns.

Monitoring Recommendations

  • Forward 9Router access logs and reverse-proxy logs into a centralized analytics platform for correlation with provider billing telemetry.
  • Monitor LLM provider dashboards for anomalous token spend and unauthorized model enumeration.
  • Track deployments to confirm custom-server.js is in the request path and alert if Next.js is reachable directly.

How to Mitigate CVE-2026-56681

Immediate Actions Required

  • Upgrade all 9Router deployments to version 0.5.6 or later without delay.
  • Rotate API keys and any LLM provider credentials configured in the instance, and audit provider usage for unauthorized consumption.
  • Restrict network exposure of the Next.js port so it is reachable only through the trusted reverse proxy that runs custom-server.js.
  • Review reverse-proxy configuration to ensure inbound X-9r-Real-Ip, X-Forwarded-For, and X-9r-Via-Proxy headers from clients are stripped before forwarding.

Patch Information

The fix is delivered in 9Router v0.5.6. The patch, tracked in GitHub commit efd20be, rewrites the trust logic to anchor origin classification to the unspoofable TCP peer address. Forwarding headers are honored only when the socket peer is itself a loopback reverse proxy. Full details are in GHSA-5mj8-gf6m-fhw8.

Workarounds

  • Place 9Router behind a reverse proxy configured to unconditionally strip X-9r-Real-Ip, X-Forwarded-For, and X-9r-Via-Proxy from client requests.
  • Bind Next.js to 127.0.0.1 only, and expose the service exclusively through the sanitizing custom-server.js wrapper.
  • Enforce API-key validation at the reverse-proxy layer for all /api/v1/* routes as a defense-in-depth control until patching is complete.
bash
# NGINX example: strip spoofable headers before forwarding to 9Router
location /api/v1/ {
    proxy_set_header X-9r-Real-Ip "";
    proxy_set_header X-Forwarded-For "";
    proxy_set_header X-9r-Via-Proxy "";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://127.0.0.1:3000;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.