Ssrf Server Side in Fastapi with Api Keys
Ssrf Server Side in Fastapi with Api Keys — how this specific combination creates or exposes the vulnerability
Server-Side Request Forgery (SSRF) in FastAPI applications that rely on API keys for authentication can introduce subtle trust boundaries. When an endpoint accepts a user-supplied URL and makes an outbound request using server-side credentials (such as API keys stored in environment variables or injected configs), the server may inadvertently expose internal services or bypass egress restrictions.
In this scenario, API keys are typically treated as a strong authentication signal. Developers may assume that because the request is authenticated with a key, the destination is safe. However, SSRF targets the server’s ability to initiate requests, not the client’s ability to authenticate. An attacker can supply a URL pointing to internal metadata services (e.g., http://169.254.169.254 on cloud environments), local network interfaces, or internal Kubernetes endpoints. The server, using its elevated permissions and API keys, forwards the request and returns the response, leading to data exposure or lateral movement within the network.
FastAPI does not inherently validate the destination of outgoing requests. If the application uses common HTTP clients (e.g., httpx or requests) and passes user input directly into the URL parameter, the SSRF vector remains open even when API keys protect inbound authentication. For example, an endpoint that retrieves a remote configuration file might accept a source_url query parameter and call it with an API key stored in a header. An attacker can supply http://localhost:8000/admin or a cloud metadata URL, and the server’s outbound request will include the privileged API key, potentially accessing admin panels or metadata that would otherwise be unreachable.
The combination of SSRF and API keys is particularly dangerous in microservice architectures where services communicate internally using short-lived tokens or static keys. If the compromised endpoint is used during CI/CD or by automated tooling, the leaked key can lead to further compromise. Moreover, SSRF can be used to scan internal networks, exploit misconfigured services, or chain with other vulnerabilities such as insecure deserialization or remote code execution.
middleBrick detects SSRF as part of its 12 parallel security checks. When scanning a FastAPI endpoint that uses API keys, the tool tests whether user-supplied inputs can influence outbound requests and whether sensitive internal endpoints become reachable. The scan operates in an unauthenticated mode and does not modify your application; it only reports whether the attack surface allows unintended network interactions.
Api Keys-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on strict input validation, network segregation, and limiting the scope of outbound requests. Do not rely on API keys to enforce destination safety; instead, ensure the destination itself is controlled and safe.
1. Validate and restrict target URLs
Maintain an allowlist of permitted hosts or use a strict prefix (e.g., only https://api.external.com). Reject any URL that points to private IP ranges, localhost, or cloud metadata addresses.
from fastapi import FastAPI, HTTPException, Query
import httpx
import re
from ipaddress import ip_address, IPv4Address, IPv6Address
app = FastAPI()
# Allowlist approach: only permit known safe domains
ALLOWED_DOMAINS = {"api.external.com", "data.example.org"}
def is_allowed_url(url: str) -> bool:
# Basic parse and host check
from urllib.parse import urlparse
parsed = urlparse(url)
if parsed.scheme not in {"http", "https"}:
return False
host = parsed.hostname or ""
if host in ALLOWED_DOMAINS:
return True
# Optionally allow by exact known endpoints
if parsed.path.startswith("/v1/resources")):
return True
return False
@app.get("/fetch")
def fetch_resource(url: str = Query(..., description="Remote resource URL")):
if not is_allowed_url(url):
raise HTTPException(status_code=400, detail="URL not permitted")
headers = {"Authorization": "Bearer YOUR_API_KEY"}
with httpx.Client(timeout=5.0) as client:
resp = client.get(url, headers=headers)
resp.raise_for_status()
return {"status": resp.status_code, "data": resp.text[:500]}
2. Use outbound network controls and service accounts
Run your FastAPI service with minimal network reachability. If external calls are required, use a dedicated service account with limited permissions and avoid embedding long-lived API keys in code. Prefer workload identity or managed secrets injection with short TTLs.
3. Avoid passing user input to low-level request constructors
Do not construct request objects by concatenating user strings. Use typed parameters and validate each component separately. For example, prefer explicit host and path parameters rather than a free-form URL.
@app.get("/resource")
def get_resource(remote_host: str = Query(..., description="Trusted hostname"), remote_path: str = Query(..., description="Safe path")):
# Validate remote_host against a strict allowlist
if remote_host != "api.external.com":
raise HTTPException(status_code=400, detail="Host not allowed")
url = f"https://{remote_host}{remote_path}"
headers = {"X-API-Key": "YOUR_API_KEY"}
with httpx.Client() as client:
response = client.get(url, headers=headers)
return {"data": response.json()}
4. Monitor and rotate keys
Even with strict validation, treat API keys as potentially exposed. Rotate keys regularly and monitor for anomalous outbound traffic from your service. middleBrick’s continuous monitoring can help detect unusual patterns that may indicate SSRF abuse or key leakage.