CVE-2026-55638
9router: Unauthenticated LLM proxy access via /codex rewrite authorization bypass
9Router is an AI router & token saver. Prior to 0.5.2, 9router protects /v1, /v1beta, /api/v1, and /api/v1beta in src/dashboardGuard.js but omits /codex before next.config.mjs rewrites /codex/* to /api/v1/responses. A remote unauthenticated attacker can send requests to /codex/* to bypass the API-key gate and cause the server to make upstream provider calls using operator-stored LLM provider credentials. This issue is fixed in version 0.5.2.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.6
9router: Unauthenticated LLM proxy access via /codex rewrite authorization bypass
9Router is an AI router & token saver. Prior to 0.5.2, 9router protects /v1, /v1beta, /api/v1, and /api/v1beta in src/dashboardGuard.js but omits /codex before next.config.mjs rewrites /codex/* to /api/v1/responses. A remote unauthenticated attacker can send requests to /codex/* to bypass the API-key gate and cause the server to make upstream provider calls using operator-stored LLM provider credentials. This issue is fixed in version 0.5.2.
- Record
CVE-2026-55638- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H - Weakness
- CWE-862, CWE-863
- Updated
- 2026-11-02
EUVDEUVD-2026-42931
8.6
9Router is an AI router & token saver. Prior to 0.5.2, 9router protects /v1, /v1beta, /api/v1, and /api/v1beta in src/dashboardGuard.js but omits /codex before next.config.mjs rewrites /codex/* to /api/v1/responses. A remote unauthenticated attacker can send requests to /codex/* to bypass the API-key gate and cause the server to make upstream provider calls using operator-stored LLM provider credentials. This issue is fixed in version 0.5.2.
- Record
EUVD-2026-42931- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-8gmq-j984-vp4r
8.6
9router: Unauthenticated LLM proxy access via /codex rewrite authorization bypass
Summary
9router exposes an OpenAI/Anthropic-compatible LLM proxy. Remote access to this proxy is intended to be protected by an API-key check in the Next.js middleware.
However, 9router also defines a rewrite that maps /codex/* to the backend LLM endpoint /api/v1/responses. The middleware authorization decision is made on the incoming request path before the rewrite is applied. Because /codex is not included in the middleware's protected LLM API prefix list, requests to /codex/* bypass the API-key gate and are later rewritten to the same backend used by /api/v1/responses.
As a result, an unauthenticated remote attacker can access the LLM proxy through /codex/* and cause the server to make upstream provider calls using the operator-stored LLM provider credentials.
Details
| Component | File | Note |
| ----------------------------- | ----------------------------------- | ------------------------------------------------------------------------- |
| Middleware authorization gate | src/dashboardGuard.js | Protects /v1, /v1beta, /api/v1, and /api/v1beta, but not /codex |
| Rewrite configuration | next.config.mjs | Rewrites /codex/:path* to /api/v1/responses |
| LLM backend route | src/app/api/v1/responses/route.js | Dispatches rewritten requests to the LLM handler |
| Chat handler | src/sse/handlers/chat.js | Uses operator-stored provider credentials for upstream calls |
Tested version:
| Version / Commit | Runtime | Status |
| ------------------------------------------------------------ | ---------------- | -------- |
| v0.4.80, commit 23da7b1fe3bb8edd2bdbdb63fbbb15a476b02c56 | Next.js 16.2.9 | Affected |
Root Cause
The middleware classifies requests by the original incoming pathname. The protected public LLM API prefixes are:
PUBLIC_PREFIXES = ["/v1", "/v1beta", "/api/v1", "/api/v1beta"];
Because /codex is not included in this list, a request such as /codex/x does not enter the LLM API authorization branch and falls through to:
return NextResponse.next();
The rewrite configuration then maps the allowed request to the protected backend route:
{
source: "/codex/:path*",
destination: "/api/v1/responses"
}
The backend route reaches the same handler used by the canonical LLM endpoint:
return await handleChat(request);
The handler then processes the request and performs the upstream LLM provider call. In the tested configuration, the handler does not repeat the same middleware API-key gate for remote callers, so the rewritten request is served after bypassing the intended authorization check.
PoC
The following requests use the same target server and the same remote-style Host header. The only meaningful difference is the request path.
Case 01 — Protected canonical endpoint rejects unauthenticated access
POST /api/v1/responses HTTP/1.1
Host: evil.attacker.com
Content-Type: application/json
Content-Length: 156
{"model":"fakeoai/x","input":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello","messages":[{"role":"user","content":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello"}]}
Observed result:
HTTP/1.1 401 Unauthorized
This confirms that the canonical /api/v1/responses path is protected by the intended API-key gate.
Case 02 — Rewritten /codex/* path bypasses the API-key gate
POST /codex/x HTTP/1.1
Host: evil.attacker.com
Content-Type: application/json
Content-Length: 156
{"model":"fakeoai/x","input":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello","messages":[{"role":"user","content":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello"}]}
Observed result:
HTTP/1.1…
- Record
GHSA-8gmq-j984-vp4r- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H - Weakness
- CWE-862, CWE-863
- Updated
- 2026-11-02
NVD
8.6
9Router is an AI router & token saver. Prior to 0.5.2, 9router protects /v1, /v1beta, /api/v1, and /api/v1beta in src/dashboardGuard.js but omits /codex before next.config.mjs rewrites /codex/* to /api/v1/responses. A remote unauthenticated attacker can send requests to /codex/* to bypass the API-key gate and cause the server to make upstream provider calls using operator-stored LLM provider credentials. This issue is fixed in version 0.5.2.
- Record
CVE-2026-55638- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H - Weakness
- CWE-862, CWE-863
- Updated
- 2026-11-02
OSV
8.6
9router: Unauthenticated LLM proxy access via /codex rewrite authorization bypass
9Router is an AI router & token saver. Prior to 0.5.2, 9router protects /v1, /v1beta, /api/v1, and /api/v1beta in src/dashboardGuard.js but omits /codex before next.config.mjs rewrites /codex/* to /api/v1/responses. A remote unauthenticated attacker can send requests to /codex/* to bypass the API-key gate and cause the server to make upstream provider calls using operator-stored LLM provider credentials. This issue is fixed in version 0.5.2.
- Record
CVE-2026-55638- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H - Weakness
- CWE-862, CWE-863
- Updated
- 2026-11-02
OSVGHSA-8gmq-j984-vp4r
8.6
9router: Unauthenticated LLM proxy access via /codex rewrite authorization bypass
Summary
9router exposes an OpenAI/Anthropic-compatible LLM proxy. Remote access to this proxy is intended to be protected by an API-key check in the Next.js middleware.
However, 9router also defines a rewrite that maps /codex/* to the backend LLM endpoint /api/v1/responses. The middleware authorization decision is made on the incoming request path before the rewrite is applied. Because /codex is not included in the middleware's protected LLM API prefix list, requests to /codex/* bypass the API-key gate and are later rewritten to the same backend used by /api/v1/responses.
As a result, an unauthenticated remote attacker can access the LLM proxy through /codex/* and cause the server to make upstream provider calls using the operator-stored LLM provider credentials.
Details
| Component | File | Note |
| ----------------------------- | ----------------------------------- | ------------------------------------------------------------------------- |
| Middleware authorization gate | src/dashboardGuard.js | Protects /v1, /v1beta, /api/v1, and /api/v1beta, but not /codex |
| Rewrite configuration | next.config.mjs | Rewrites /codex/:path* to /api/v1/responses |
| LLM backend route | src/app/api/v1/responses/route.js | Dispatches rewritten requests to the LLM handler |
| Chat handler | src/sse/handlers/chat.js | Uses operator-stored provider credentials for upstream calls |
Tested version:
| Version / Commit | Runtime | Status |
| ------------------------------------------------------------ | ---------------- | -------- |
| v0.4.80, commit 23da7b1fe3bb8edd2bdbdb63fbbb15a476b02c56 | Next.js 16.2.9 | Affected |
Root Cause
The middleware classifies requests by the original incoming pathname. The protected public LLM API prefixes are:
PUBLIC_PREFIXES = ["/v1", "/v1beta", "/api/v1", "/api/v1beta"];
Because /codex is not included in this list, a request such as /codex/x does not enter the LLM API authorization branch and falls through to:
return NextResponse.next();
The rewrite configuration then maps the allowed request to the protected backend route:
{
source: "/codex/:path*",
destination: "/api/v1/responses"
}
The backend route reaches the same handler used by the canonical LLM endpoint:
return await handleChat(request);
The handler then processes the request and performs the upstream LLM provider call. In the tested configuration, the handler does not repeat the same middleware API-key gate for remote callers, so the rewritten request is served after bypassing the intended authorization check.
PoC
The following requests use the same target server and the same remote-style Host header. The only meaningful difference is the request path.
Case 01 — Protected canonical endpoint rejects unauthenticated access
POST /api/v1/responses HTTP/1.1
Host: evil.attacker.com
Content-Type: application/json
Content-Length: 156
{"model":"fakeoai/x","input":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello","messages":[{"role":"user","content":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello"}]}
Observed result:
HTTP/1.1 401 Unauthorized
This confirms that the canonical /api/v1/responses path is protected by the intended API-key gate.
Case 02 — Rewritten /codex/* path bypasses the API-key gate
POST /codex/x HTTP/1.1
Host: evil.attacker.com
Content-Type: application/json
Content-Length: 156
{"model":"fakeoai/x","input":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello","messages":[{"role":"user","content":"NINEROUTER_CODEX_AUTH_BYPASS_MARKER hello"}]}
Observed result:
HTTP/1.1…
- Record
GHSA-8gmq-j984-vp4r- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H - Weakness
- CWE-862, CWE-863
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
9routernpm |
before 0.5.2 | 0.5.2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-55638 is a high vulnerability (CVSS 8.6) in Decolua 9router, published July 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 6.58%, the 93rd percentile. Fixed in 9router 0.5.2.
References
github.com/decolua/9router/security/advisories/GHSA-8gmq-j984-vp4r
github.com/decolua/9router/commit/b282f0554972ea35281520738759d76abcd0b0b3
github.com/decolua/9router/releases/tag/v0.5.2
nvd.nist.gov/vuln/detail/CVE-2026-55638
github.com/advisories/GHSA-8gmq-j984-vp4r
github.com/CVEProject/cvelistV5/tree/main/cves/2026/55xxx/CVE-2026-55638.json
github.com/decolua/9router
Left out here: the rest of 2 source descriptions. The JSON record has them.