GHSA-vjc7-jrh9-9j86: 9Router: no-auth API leaks keys, chats, provider control
GHSA-vjc7-jrh9-9j86 CRITICAL9Router, an LLM gateway/router package with 4,631 downstream dependents, ships several dashboard API routes — /api/providers, /api/usage/stats, /api/usage/request-logs and /api/usage/request-details — with zero authentication, so anyone who can reach the endpoint can create, read, modify or delete every configured AI provider connection and pull plaintext API keys, OAuth tokens, and complete conversation histories including system prompts, user messages and assistant responses. This is a CVSS 10.0 (AV:N/AC:L/PR:N/UI:N/C:H/I:H/A:H) flaw exploitable with a single unauthenticated curl request and no client interaction — EPSS is not yet scored and there's no known public exploit or Nuclei template, but the barrier to exploitation is effectively zero, and it is not (yet) in CISA KEV, which likely just means it hasn't been mass-scanned. Because 9Router centralizes credentials for multiple downstream AI providers, this is functionally equivalent to handing an attacker root access to every connected OpenAI/Anthropic/other account plus a live wiretap on every user's prompts and responses routed through it. There is no patched version referenced yet (fixed in a release above 0.4.41), so any deployment should be taken off the public internet or placed behind a network ACL/authenticating proxy immediately, all API keys stored in it rotated, and provider configs/usage logs audited for unrecognized entries. Given trivial exploitability, complete CIA impact, and the credential-concentration risk inherent to AI gateways, this warrants a breaking alert to any team running 9Router.
What is the risk?
Critical and immediately actionable. Exploitability is trivial: no authentication, no rate limiting, and a handful of unauthenticated curl requests are sufficient to fully compromise the system (CVSS 3.1 base score 10.0). Impact is total — confidentiality (plaintext API keys, OAuth tokens, full conversation contents), integrity (arbitrary provider CRUD allows redirecting traffic through attacker-controlled endpoints), and availability (deleting all providers causes denial of service) are all fully compromised. Exposure depends on whether the 9Router dashboard/API is reachable from the internet or restricted to internal networks — any internet-facing instance should be treated as already compromised until proven otherwise. No EPSS score, KEV listing, or public exploit/scanner template exists yet, but the near-zero skill required to exploit this means real-world exploitation, once discovered, will likely happen fast and at scale (mass scanning is trivial to automate against exposed instances).
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| OpenAI Node | npm | <= 0.4.41 | No patch |
Do you use OpenAI Node? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 step-
1) Upgrade past 0.4.41 as soon as a fixed release is published (root cause: missing auth middleware on /api/providers/* and /api/usage/*, per the maintainer's own advisory). 2) Until a patch is confirmed, take the dashboard/API off the public internet or place it behind a network ACL, VPN, or authenticating reverse proxy. 3) Rotate every API key and OAuth token that was ever configured in 9Router, since full plaintext keys have been exposed via /api/usage/stats. 4) Audit /api/providers entries for unrecognized or unexpected provider connections (possible rogue-provider injection) and review request-logs for anomalous access patterns or unfamiliar source IPs. 5) Long-term: implement authentication + per-tenant authorization on every /api/providers and /api/usage route, mask API keys in all API responses (never return full key strings), and add rate limiting to public endpoints as the advisory recommends.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is GHSA-vjc7-jrh9-9j86?
9Router, an LLM gateway/router package with 4,631 downstream dependents, ships several dashboard API routes — /api/providers, /api/usage/stats, /api/usage/request-logs and /api/usage/request-details — with zero authentication, so anyone who can reach the endpoint can create, read, modify or delete every configured AI provider connection and pull plaintext API keys, OAuth tokens, and complete conversation histories including system prompts, user messages and assistant responses. This is a CVSS 10.0 (AV:N/AC:L/PR:N/UI:N/C:H/I:H/A:H) flaw exploitable with a single unauthenticated curl request and no client interaction — EPSS is not yet scored and there's no known public exploit or Nuclei template, but the barrier to exploitation is effectively zero, and it is not (yet) in CISA KEV, which likely just means it hasn't been mass-scanned. Because 9Router centralizes credentials for multiple downstream AI providers, this is functionally equivalent to handing an attacker root access to every connected OpenAI/Anthropic/other account plus a live wiretap on every user's prompts and responses routed through it. There is no patched version referenced yet (fixed in a release above 0.4.41), so any deployment should be taken off the public internet or placed behind a network ACL/authenticating proxy immediately, all API keys stored in it rotated, and provider configs/usage logs audited for unrecognized entries. Given trivial exploitability, complete CIA impact, and the credential-concentration risk inherent to AI gateways, this warrants a breaking alert to any team running 9Router.
Is GHSA-vjc7-jrh9-9j86 actively exploited?
No confirmed active exploitation of GHSA-vjc7-jrh9-9j86 has been reported, but organizations should still patch proactively.
How to fix GHSA-vjc7-jrh9-9j86?
1) Upgrade past 0.4.41 as soon as a fixed release is published (root cause: missing auth middleware on /api/providers/* and /api/usage/*, per the maintainer's own advisory). 2) Until a patch is confirmed, take the dashboard/API off the public internet or place it behind a network ACL, VPN, or authenticating reverse proxy. 3) Rotate every API key and OAuth token that was ever configured in 9Router, since full plaintext keys have been exposed via /api/usage/stats. 4) Audit /api/providers entries for unrecognized or unexpected provider connections (possible rogue-provider injection) and review request-logs for anomalous access patterns or unfamiliar source IPs. 5) Long-term: implement authentication + per-tenant authorization on every /api/providers and /api/usage route, mask API keys in all API responses (never return full key strings), and add rate limiting to public endpoints as the advisory recommends.
What systems are affected by GHSA-vjc7-jrh9-9j86?
This vulnerability affects the following AI/ML architecture patterns: LLM gateway/routing layer, multi-provider API key/credential management, model serving and inference proxying, agent frameworks relying on gateway-managed provider credentials.
What is the CVSS score for GHSA-vjc7-jrh9-9j86?
GHSA-vjc7-jrh9-9j86 has a CVSS v3.1 base score of 10.0 (CRITICAL).
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0012 Valid Accounts AML.T0025 Exfiltration via Cyber Means AML.T0049 Exploit Public-Facing Application AML.T0055 Unsecured Credentials AML.T0056 Extract LLM System Prompt AML.T0057 LLM Data Leakage Compliance Controls Affected
What are the technical details?
Original Advisory
--- title: Unauthenticated CRUD on /api/providers and Full API Key Leak via /api/usage/stats product: 9Router version: <= 0.4.41 severity: critical cve_request: true --- ## Summary Multiple critical API security vulnerabilities were discovered in 9Router's Next.js dashboard. The `/api/providers` endpoints lack authentication entirely, allowing anyone to create, read, update, and delete provider connections. Additionally, `/api/usage/stats` exposes full plaintext API keys, and `/api/usage/request-logs` + `/api/usage/request-details` expose all users' request history and full conversation contents (including system prompts, user messages, assistant responses) without authentication. ## Affected Endpoints | Endpoint | Method | Issue | |---|---|---| | `/api/providers` | GET | Lists all provider connections with partial credentials, OAuth tokens, account IDs | | `/api/providers/:id` | GET | Read any single provider detail (IDOR) | | `/api/providers` | POST | Create arbitrary provider connections with attacker-controlled API keys | | `/api/providers/:id` | PUT | Modify any existing provider connection | | `/api/providers/:id` | DELETE | Delete any provider connection | | `/api/usage/stats` | GET | Exposes full plaintext API keys, per-account usage breakdown, cost data | | `/api/usage/request-logs` | GET | Exposes all users' request logs (model, tokens, cost, timestamp, provider) | | `/api/usage/request-details/:id` | GET | Exposes full conversation turns including system prompts, user messages, assistant responses | | `/api/version` | GET | Exposes current version info | | `/api/models` | GET | Exposes full model routing catalog | | `/api/v1/models` | GET | Exposes model list | ## Impact ### Critical: Provider CRUD without authentication An attacker can: 1. **Add a malicious provider** — inject a provider that proxies through their server, capturing all prompts, responses, and API keys routed through 9Router 2. **Modify existing providers** — replace API keys with attacker-controlled ones, redirect traffic 3. **Delete all providers** — cause complete denial of service 4. **Read all provider configurations** — harvest partial credentials, GitHub Copilot OAuth tokens, Cloudflare account IDs, email addresses ### Critical: Full API key leak via /api/usage/stats The endpoint returns complete API key strings (e.g., `sk-...`) in plaintext alongside usage data per key, enabling unauthorized use of connected AI provider accounts. ### Critical: Conversation history leak `/api/usage/request-details` returns the full conversation history of other users' AI sessions, including system prompts, user messages, assistant responses, tool calls, and reasoning traces. ## Steps to Reproduce ### 1. Unauthenticated read of all providers ```bash curl -s https://<host>/api/providers ``` Returns all provider connections with email addresses, auth type, account IDs, and partial API key prefixes. ### 2. Create a provider without authentication ```bash curl -X POST https://<host>/api/providers \ -H "Content-Type: application/json" \ -d '{"provider":"openai","authType":"apikey","name":"rogue","apiKey":"sk-attacker-controlled"}' ``` Returns the created connection object with a new UUID and `isActive: true`. ### 3. Modify an existing provider without authentication ```bash curl -X PUT https://<host>/api/providers/<existing-uuid> \ -H "Content-Type: application/json" \ -d '{"name":"modified","apiKey":"sk-attacker-key"}' ``` Returns the updated connection object. ### 4. Delete a provider without authentication ```bash curl -X DELETE https://<host>/api/providers/<existing-uuid> ``` Returns `{"message":"Connection deleted successfully"}`. ### 5. Read full usage stats with API keys ```bash curl -s https://<host>/api/usage/stats ``` Returns full API key strings, per-account token/cost breakdown, recent requests. ### 6. Read request logs ```bash curl -s "https://<host>/api/usage/request-logs?page=1&pageSize=50" ``` Returns paginated request logs with timestamps, models, providers, user emails, token counts. ### 7. Read full conversation ```bash curl -s https://<host>/api/usage/request-details/<request-uuid> ``` Returns complete conversation turns for that request. ### 8. Read version info ```bash curl -s https://<host>/api/version ``` Returns `{"currentVersion":"0.4.19","latestVersion":"0.4.45","hasUpdate":true}`. ## Root Cause The Next.js API routes under `src/app/api/*` lack authentication middleware on several endpoints. Specifically: - `/api/providers/*` — No auth check before CRUD operations on provider connections stored in the database - `/api/usage/stats` — No auth check before returning aggregated usage data including full API keys - `/api/usage/request-logs` — No auth check before returning request history - `/api/usage/request-details/:id` — No auth check before returning full conversation contents ## Suggested Fix 1. Add authentication middleware to all `/api/providers/*` routes (GET, POST, PUT, DELETE) 2. Add authentication middleware to all `/api/usage/*` routes 3. Never return full API key strings in any API response — return masked keys only 4. Never return GitHub Copilot tokens or similar OAuth secrets in API responses 5. Implement proper authorization checks so users can only access their own data 6. Add rate limiting to public endpoints ## Resources - https://github.com/decolua/9router
Exploitation Scenario
An attacker discovers or is pointed at an internet-facing 9Router instance (e.g., via Shodan/Censys banner matching or the exposed /api/version endpoint). They first run `curl /api/providers` to enumerate existing provider connections, partial credentials, and account IDs with zero authentication. They then POST a new malicious provider entry pointing to an attacker-controlled proxy endpoint, or PUT-modify an existing provider's API key to one they control — silently rerouting some or all future AI traffic through their infrastructure and capturing every prompt and response in transit. In parallel, they hit /api/usage/stats to harvest full plaintext API keys for every connected provider account, and pull /api/usage/request-details to read other users' complete conversation histories, including system prompts and any sensitive data users pasted into prompts. As a final step, they could DELETE all provider connections to cause an outage, or simply leave their rogue provider in place for long-term, low-noise data exfiltration and API-key abuse (running up costs or exfiltrating proprietary data on the victim's provider accounts).
Weaknesses (CWE)
CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
Primary
CWE-306 Missing Authentication for Critical Function
Primary
CWE-862 Missing Authorization
Primary
CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
- [Architecture and Design] Compartmentalize the system to have "safe" areas where trust boundaries can be unambiguously drawn. Do not allow sensitive data to go outside of the trust boundary and always be careful when interfacing with a compartment outside of the safe area. Ensure that appropriate compartmentalization is built into the system design, and the compartmentalization allows for and reinforces privilege separation functionality. Architects and designers should rely on the principle of least privilege to decide the appropriate time to use privileges and the time to drop privileges.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H References
Timeline
Related Vulnerabilities
CVE-2025-61260 9.8 OpenAI Codex CLI: RCE via malicious MCP config files
Same package: openai CVE-2024-23827 9.8 Nginx-UI: arbitrary file write via cert import leads to RCE
Same package: openai GHSA-gqqj-85qm-8qhf 8.7 paperclipai: connector trust bypass enables Gmail read/write
Same package: openai CVE-2026-67425 8.6 Flyto2 Core: SSRF leaks LLM API keys via base_url
Same package: openai CVE-2024-22197 7.7 Nginx-UI: authenticated command injection to RCE
Same package: openai