Sep 22, 2026·7 min read·5 visits
A login lockout bypass in 9Router < 0.5.6 allows remote attackers to conduct unthrottled brute-force attacks against administrative credentials by spoofing the X-9r-Real-Ip HTTP header.
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.
9Router is an open-source AI router and token-saving proxy. To prevent brute-force attacks against its administrative control panel, the application integrates a rate-limiting and progressive lockout mechanism on its login endpoint. This mechanism tracks failed login attempts and locks out the corresponding client IP address after 5 consecutive failures.
The vulnerability, tracked as CVE-2026-56682 and GHSA-32gc-64m7-hj7v, exists because the login rate-limiting logic trusts client-supplied HTTP headers to identify the source of incoming requests. Specifically, the component relies on the X-9r-Real-Ip header to determine the remote client's identity without validating if the connection originates from a trusted reverse proxy.
Because this trust boundary is not properly enforced, an unauthenticated attacker can arbitrarily define this header value. By systematically rotating the value of X-9r-Real-Ip on each successive authentication request, the attacker can associate each attempt with a unique, virtual IP address. This bypasses the lockout mechanism entirely, allowing unthrottled dictionary attacks against the administrative credentials.
The core security flaw resides in the rate-limiting architecture implemented in src/lib/auth/loginLimiter.js. When a login request is made to POST /api/auth/login, the application attempts to retrieve the client's genuine IP address to track failed authentication attempts. The rate limiter is designed to track these failures in memory-based buckets mapped to the returned IP address.
To resolve the client IP address in reverse-proxy environments, the application retrieves the value of the X-9r-Real-Ip header. The system relies on a custom server wrapper (custom-server.js) to strip incoming proxy headers from untrusted connections and rewrite them based on the actual socket peer address. However, this implementation breaks down under two conditions.
First, if the Next.js application is deployed directly or accessed directly bypassing the custom-server.js wrapper (for example, by directly accessing the internal Next.js port 3000), the incoming HTTP headers are passed to the routing context completely unmodified. In this state, an attacker can directly inject and control the X-9r-Real-Ip header. Second, prior to version 0.5.6, the custom server's proxy validation checks were insufficient, trusting forwarding headers simply if they were present on the request, regardless of whether the physical TCP connection originated from a trusted local loopback address.
This structural trust flaw allows an attacker to manipulate the identifier used to resolve the rate-limiting bucket. Since the bucket tracking failure counts is keyed on this header value, rotating the IP address string on each request ensures that no individual tracking bucket ever reaches the threshold of 5 failed attempts required to trigger a progressive lockout.
An analysis of the fix in commit efd20be8d81ef2e256a7037f3aa78e6b567b5fd3 reveals how the trust boundary was re-established. The vulnerable wrapper implementation trusted any forwarding headers unconditionally. The patch introduces a strict Loopback Proxy Trust Model within custom-server.js.
The following code diff illustrates the exact changes made to resolve the validation gap:
// custom-server.js - Patch Analysis
const wrapped = (req, res) => {
// 1. Retrieve the actual physical remote IP address from the network socket
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);
// 2. Validate if the TCP socket connection originates from a trusted local loopback interface
const isLoopbackProxy = socketIp === "127.0.0.1" || socketIp === "::1" || socketIp === "::ffff:127.0.0.1";
// 3. Resolve the proxy IP only if the connection is from localhost
const proxyIp = xRealIp || (xff ? String(xff).split(",")[0].trim() : "");
const ip = isLoopbackProxy && proxyIp ? proxyIp : socketIp;
// 4. Strip client-supplied tracking headers to prevent downstream contamination
delete req.headers["x-9r-real-ip"];
delete req.headers["x-forwarded-for"];
delete req.headers["x-9r-via-proxy"];
// 5. Explicitly set the sanitized IP address
req.headers["X-9r-Real-Ip"] = ip;
}The patched code ensures that forwarding headers are only parsed if the TCP peer address (socketIp) matches a validated loopback address (127.0.0.1, ::1, or the IPv4-mapped IPv6 representation ::ffff:127.0.0.1). If the request is received from an external network socket, the forwarding headers are completely ignored, and the actual socket connection IP is used as the client identifier. This prevents remote attackers from supplying arbitrary IP strings to rotate rate-limiting buckets.
Exploitation of this vulnerability requires network access to the 9Router administrative login endpoint. There are no prerequisite permissions or user roles required, as the bypass occurs during the initial authentication phase before any credentials are validated.
The attack vector can be visualized as a structured request pipeline where the client dynamically generates a random IPv4 address for the tracking header on each request. The following sequence diagram outlines this traffic flow:
Because the rate-limiting tracking is distributed across separate, distinct address keys, the login progressive lockout threshold is never reached for any single bucket. This allows the attacker to execute multi-threaded password brute-forcing operations until a valid credential matches, leading to a successful administrative session.
The security impact of CVE-2026-56682 is classified as Medium, with a CVSS v3.1 base score of 5.3. Although the vulnerability does not directly result in remote code execution (RCE) or immediate database compromise, it serves as a high-fidelity entry point for administrative takeover.
An attacker who successfully bypasses the lockout mechanism can conduct highly effective brute-force or dictionary attacks against the primary administrative login password. 9Router coordinates access to backend LLM providers and billing APIs; gaining access to the administrative dashboard grants the attacker control over configuration keys, token savings routes, and connected upstream API tokens.
Furthermore, the severity may escalate to High in deployments using default or weak passwords. In environments where the Next.js service is directly exposed on an unprotected public port, the mitigation provided in custom-server.js is rendered inactive, creating a persistent risk vector.
To fully mitigate the risks associated with CVE-2026-56682, administrators must deploy both software patches and structural network controls.
The primary remediation path is upgrading the 9Router deployment to version 0.5.6 or later. This release enforces the Loopback Proxy Trust Model, ignoring any forwarding headers received from non-loopback TCP sockets and stripping tracking headers from untrusted clients.
In scenarios where immediate patching is not feasible, the following workarounds should be applied:
127.0.0.1 or ::1). This prevents attackers from directly connecting to the Next.js application port (e.g., 3000) and bypassing the custom wrapper server.X-9r-Real-Ip, X-Forwarded-For, and X-Real-IP before forwarding traffic to the 9Router backend.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
9Router decolua | < 0.5.6 | 0.5.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-307 / CWE-807 |
| Attack Vector | Network (Remote) |
| CVSS Score | 5.3 (Medium) |
| Exploit Status | Proof-of-Concept |
| KEV Status | Not Listed |
| Ransomware Use | No |
The application fails to properly enforce limits on how many times an entity can attempt to authenticate within a given timeframe.
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.
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.
A vulnerability exists in the i18n middleware of nginx-ignition, enabling CPU amplification attacks. By transmitting a crafted Accept-Language header containing malformed tags separated by underscores, an unauthenticated remote attacker can bypass the length-guard threshold of the underlying Go parsing library. Normalization of underscores to hyphens occurs after the initial validation checks, forcing the parser into expensive quadratic-time loops that consume 100% of available CPU resources. This leads to a complete denial of service for the administrative API and potentially degrades the availability of the hosting system. This vulnerability has been resolved in version 2.40.1.