- Location
- app/core/security.py:43
- Finding
- Unrestricted Server-Side Request Forgery in the URL Fetch Endpoint<![CDATA[
## Vulnerability Details
**File Location**: `app/core/security.py:43-52`, `app/routers/proxy.py:75-84`, `app/managers/proxy_manager.py:221-240`
**Vulnerability Type**: Server-Side Request Forgery (SSRF)
**Risk Level**: Critical
### Vulnerable Code
```python
# app/core/security.py:43-52
def validate_url(url: Optional[str]) -> bool:
"""
Validate URL format.
- Must start with http:// or https://
"""
if not url:
return False
return url.startswith(("http://", "https://"))
```
```python
# app/routers/proxy.py:75-84
from app.core.security import validate_url
if not validate_url(fetch_request.url):
return JSONResponse(
status_code=400,
content={
"success": False,
"error": "Invalid URL",
"message": "URL must start with http:// or https://"
}
)
```
```python
# app/managers/proxy_manager.py:221-240
proxy_url = f"http://127.0.0.1:{self.clash_mixed_port}"
transport = httpx.AsyncHTTPTransport(proxy=proxy_url)
async with httpx.AsyncClient(
timeout=30.0,
follow_redirects=True,
transport=transport
) as client:
request_headers = headers or {}
request_headers.setdefault("User-Agent", "ProxyGateway/0.3.0")
response = await client.request(
method=method.upper(),
url=url,
headers=request_headers,
content=body
)
```
### Technical Analysis
The URL validation only verifies that the supplied string begins with `http://` or `https://`. It does not parse and validate the destination hostname, resolve DNS addresses, restrict destination ports, or reject loopback, private, link-local, reserved, multicast, and cloud metadata addresses.
The forwarding implementation accepts a caller-controlled method, URL, headers, and body. It also enables automatic redirects without validating each redirect destination. Consequently, an external caller can instruct the server to make requests to resources reachable from the serve
...[truncated 1860 chars]
- Remediation
- <![CDATA[
## Remediation Suggestions
1. Parse URLs with a standards-compliant URL parser and permit only explicitly supported schemes.
2. Resolve the destination hostname before connecting and reject all loopback, private, link-local, unspecified, multicast, reserved, and documentation address ranges for both IPv4 and IPv6.
3. Check every resolved address, not only the first DNS result.
4. Disable automatic redirects or validate and resolve every redirect destination before following it.
5. Protect against DNS rebinding by ensuring the validated address is the address used for the connection.
6. Restrict destination ports to a minimal allowlist, normally TCP 80 and 443.
7. Restrict methods to those required by the service. If arbitrary methods are necessary, apply a destination allowlist and stronger authorization.
8. Remove or block sensitive forwarded headers such as `Authorization`, `Cookie`, `Proxy-Authorization`, and cloud-specific headers unless explicitly required.
9. Enforce network-level egress controls so the application cannot reach metadata services, loopback services, or private network ranges.
10. Add tests covering IPv4, IPv6, encoded addresses, mixed notation, DNS rebinding, redirects, user-info URL syntax, and cloud metadata endpoints.
]]>