Sep 22, 2026·6 min read·4 visits
An authentication bypass in 9Router allows remote attackers to spoof their IP address via the X-9r-Real-Ip header and access sensitive APIs without validation.
CVE-2026-56681 is a high-severity authentication bypass vulnerability in 9Router, an AI router and token-saving proxy. The vulnerability arises from an improper trust boundary where the application relies on the client-controlled HTTP header X-9r-Real-Ip to determine whether an incoming request originates from a local (loopback) environment. In deployments where requests can reach the Next.js backend directly—bypassing the sanitizing custom-server.js wrapper—a remote, unauthenticated attacker can spoof their origin by supplying an X-9r-Real-Ip: 127.0.0.1 header.
The system architecture of 9Router employs a dual-layer setup consisting of a Next.js web application and a custom wrapper server defined in custom-server.js. This wrapper handles incoming client connections, resolves IP addresses from TCP sockets securely, sanitizes spoofable HTTP headers, and proxies requests to the Next.js backend.
Under normal execution, the system relies on this boundary to distinguish administrative loopback traffic from public clients. The core application exposes public LLM API routes under /api/v1/* which are intended to be guarded by robust API key validation mechanisms.
However, the application exposes a dangerous trust boundary by utilizing the custom header X-9r-Real-Ip to bypass security guards. If the Next.js server is directly exposed without the wrapper layer, this header falls entirely under client control, allowing unauthenticated remote access to internal API configurations.
The root cause is classified as CWE-807: Reliance on Untrusted Inputs in a Security Decision. The authentication logic inside the Next.js server utilizes a helper function named isLocalRequest() in src/dashboardGuard.js to authorize administrative operations.
This helper identifies loopback traffic by parsing the X-9r-Real-Ip header and matching it to local loopback addresses like 127.0.0.1 or ::1. It operates under the false assumption that only the trusted custom-server.js wrapper can write or forward this specific header.
If the application is deployed directly via standard platform mechanisms (such as next start on cloud providers or in bare Docker containers), the custom-server.js wrapper is completely bypassed. Consequently, an external attacker can append X-9r-Real-Ip: 127.0.0.1 to their HTTP requests. The backend evaluates this header, falsely asserts that the connection is local, and skips API key validation for all endpoints under /api/v1/*.
The vulnerability lies in how IP evaluation was handled prior to the patch. The custom-server.js file failed to properly validate if the physical socket connection originated from a loopback proxy before processing forwarding headers.
// Vulnerable logic flow in custom-server.js
const wrapped = (req, res) => {
const ip = req.socket && req.socket.remoteAddress ? req.socket.remoteAddress : "";
// Forwarding headers present = request arrived via a reverse proxy; loopback
// socket is the proxy hop, not the end-user, so it must not be trusted as local.
const viaProxy = !!(req.headers["x-forwarded-for"] || req.headers["x-real-ip"]);
// Vulnerable trust of incoming headers occurs hereThe patch introduced strict peer address verification and automated stripping of internal headers. The following diff outlines the secured logic in custom-server.js introduced in version 0.5.6:
@@ -10,10 +10,15 @@ http.createServer = (...args) => {
const rest = args.filter((a) => typeof a !== "function");
if (!handler) return origCreate(...args);
const wrapped = (req, res) => {
- const ip = req.socket && req.socket.remoteAddress ? req.socket.remoteAddress : "";
- // Forwarding headers present = request arrived via a reverse proxy; loopback
- // socket is the proxy hop, not the end-user, so it must not be trusted as local.
- const viaProxy = !!(req.headers["x-forwarded-for"] || req.headers["x-real-ip"]);
+ 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"];The patched version validates whether socketIp is a true loopback address (127.0.0.1, ::1, or the IPv4-mapped IPv6 equivalent ::ffff:127.0.0.1). If the physical socket is not local, incoming forwarding headers are ignored and stripped, neutralizing spoofing attempts.
To exploit this vulnerability, an attacker must identify a target running 9Router where the Next.js application port (typically 3000) is exposed directly to the network. Alternatively, the target may be behind a reverse proxy that fails to strip custom HTTP headers from client requests.
An attacker craft an HTTP request to the /api/v1/models endpoint while injecting the X-9r-Real-Ip header. This allows the attacker to query the state of the router without providing any Authorization headers.
GET /api/v1/models HTTP/1.1
Host: target-9router-instance:3000
X-9r-Real-Ip: 127.0.0.1
User-Agent: Mozilla/5.0
Accept: application/jsonUpon receiving this request, the backend's local request helper processes the injected header. It returns a 200 OK response containing the configured LLM providers and models, allowing the attacker to make unauthorized inferences using the host's paid API keys.
The impact of this vulnerability is significant for organizations relying on 9Router to manage LLM access. Exploitation allows unauthenticated remote actors to execute cost-incurring inference requests against configured models.
Furthermore, the bypass facilitates information disclosure of internal system configurations and API structures. Attackers can enumerate active service integrations, revealing third-party provider accounts associated with the host.
Because the vulnerability does not provide direct filesystem access or system command execution, the impact on confidentiality, integrity, and availability is rated as Low from a system standpoint, yielding a CVSS score of 7.3.
The fix introduced in version 0.5.6 successfully secures deployments that run through custom-server.js by dropping client-supplied headers. However, structural risks remain if system administrators execute the Next.js server directly via next start or similar commands.
Because the core security guard inside dashboardGuard.js was not modified to independently validate socket origins, deployments bypassing custom-server.js remain vulnerable even on version 0.5.6. The fix is only effective if the wrapper file remains the sole entry point for network traffic.
Additionally, if an upstream reverse proxy is configured to append client IPs rather than overwrite the X-Forwarded-For header, attackers might still manipulate the list parsing logic. Standard hardening must include dropping all X-9r-* headers at the network edge.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
9Router decolua | < 0.5.6 | 0.5.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-807 |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.3 |
| Exploit Status | Proof of Concept |
| CISA KEV Status | No |
| Impact | Authentication Bypass / Unauthorized Resource Consumption |
The application makes a security decision based on the content of an HTTP header that can be modified or spoofed by an external attacker.
CVE-2026-58270 identifies a Regular Expression Denial of Service (ReDoS) vulnerability in Sync-in Server prior to version 2.4.0. An authenticated attacker can supply a complex regular expression in the pathFilters parameter of the sync diff endpoint. When evaluated, this causes catastrophic backtracking, blocking the single-threaded Node.js event loop and rendering the entire server unresponsive.
A rate limiting bypass vulnerability in 9Router versions before 0.5.6 allows unauthenticated remote attackers to circumvent the login progressive lockout mechanism. By manipulating the client-supplied X-9r-Real-Ip HTTP header, an attacker can rotate the tracking IP address, enabling unthrottled brute-force password guessing against the administrative interface.
CVE-2026-58272 is a timing side-channel vulnerability in the authentication endpoint of Sync-in Server before version 2.4.1. Unauthenticated remote attackers can distinguish between valid and invalid usernames due to asymmetric execution paths. When processing invalid usernames, the database query returns early, skipping the computationally expensive bcrypt verification path that is normally triggered for valid accounts.
An input validation bypass in the CKAN MCP Server (NPM package @aborruso/ckan-mcp-server) prior to version 0.4.108 allows remote attackers to perform Server-Side Request Forgery (SSRF). The application's server URL validation mechanism checked hostnames only as literal strings without performing pre-connection DNS resolution. An attacker can bypass these checks using hostnames that resolve to loopback, private, or link-local IP addresses, including the AWS Instance Metadata Service (IMDS). This is the third documented bypass of this protection mechanism, succeeding previous incomplete mitigations in CVE-2026-33060 and CVE-2026-53509.
A security feature bypass vulnerability in the Falco k8saudit plugin (and its cloud-specific variants) allowed privileged workloads to run undetected. This bypass occurred because the plugin's default extraction logic and rules only evaluated standard containers, completely omitting initContainers and ephemeralContainers.
nginx-ignition is a web-based user interface for managing the Nginx web server. In versions 2.33.0 through 2.35.0, the application is vulnerable to an improper authentication flaw (CWE-287) in its Multi-Factor Authentication (MFA) implementation. The stateless validation of Time-Based One-Time Passwords (TOTP) allows an attacker to reuse a captured, active verification code multiple times within the standard 30-second validity window, successfully bypassing secondary authentication checks if primary credentials are known.