Ssrf Server Side in Fastapi (Python)
Ssrf Server Side in Fastapi with Python — how this specific combination creates or exposes the vulnerability
Server-side request forgery (SSRF) in FastAPI with Python occurs when an endpoint accepts a URL from a client and uses it directly with an HTTP client such as httpx or requests. FastAPI does not inherently validate or sanitize the target host, so if the developer forwards user input to internal services, cloud metadata endpoints, or restricted networks, the server can be forced to interact with unintended systems.
For example, consider a FastAPI route that fetches a remote image for processing. If the image URL is taken directly from the request and passed to httpx.get, an attacker can supply a URL pointing to the metadata service (http://169.254.169.254) or an internal Kubernetes service (http://kubernetes.default.svc). Because FastAPI runs server-side, the request originates from the host environment, which may have access to internal networks or instance metadata that external clients cannot reach.
Common Python libraries that introduce SSRF when misused include httpx, requests, and urllib. In FastAPI, developers often chain user input with logic that calls external APIs, and without hostname allowlisting or strict URL parsing, the server-side route becomes a proxy for attacker-controlled destinations. This is especially risky when the application runs in cloud environments where metadata endpoints expose credentials or when internal services are reachable only from within the network.
SSRF in this context also intersects with other security concerns such as data exposure and authentication bypass. If the FastAPI service uses shared credentials or tokens to call downstream services, an attacker can leverage SSRF to reach those endpoints and exfiltrate data. The framework’s dependency on Python’s standard libraries for URL handling means that edge cases like nested redirects, URL encoding tricks, or non-standard URI schemes (e.g., file://, gopher://) can bypass naive validation logic.
middleBrick detects SSRF as part of its 12 parallel security checks. When scanning a FastAPI endpoint, it examines input validation and whether outbound requests can be directed to sensitive internal or cloud destinations. The scanner does not fix the behavior but reports the finding with severity and remediation guidance, helping teams identify unintended proxy capabilities before an attacker does.
Python-Specific Remediation in Fastapi — concrete code fixes
To remediate SSRF in FastAPI with Python, validate and restrict all URLs that the server uses for outbound requests. Prefer allowlisting known hosts, parsing the target host explicitly, and avoiding direct use of user-supplied URLs in HTTP clients.
Below is a vulnerable FastAPI route that directly forwards a user-provided URL to httpx:
from fastapi import FastAPI, HTTPException
import httpx
app = FastAPI()
@app.get("/fetch")
async def fetch_url(url: str):
async with httpx.AsyncClient() as client:
response = await client.get(url)
return {"status_code": response.status_code, "text": response.text[:200]}
This pattern is unsafe because url can point to internal services or metadata endpoints. A safer approach is to use a validated base URL and path parameters instead of raw user input:
from fastapi import FastAPI, HTTPException, Path
import httpx
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.example.com", "static.example.com"}
app = FastAPI()
def is_allowed_host(url: str) -> bool:
parsed = urlparse(url)
return parsed.hostname in ALLOWED_HOSTS and parsed.scheme in {"https", "http"}
@app.get("/fetch")
async def fetch_url(url: str = Path(..., description="Full URL to fetch; must be from allowed hosts")):
if not is_allowed_host(url):
raise HTTPException(status_code=400, detail="Host not allowed")
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=5.0)
return {"status_code": response.status_code, "text": response.text[:200]}
For cases where you must accept a path rather than a full URL, construct the target server address on the server side:
from fastapi import FastAPI, HTTPException
import httpx
app = FastAPI()
@app.get("/items/{item_id}")
async def get_item(item_id: str):
base_url = "https://api.example.com"
url = f"{base_url}/items/{item_id}"
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=5.0)
if response.status_code != 200:
raise HTTPException(status_code=response.status_code, detail="Failed to fetch item")
return response.json()
Additional Python-specific practices include disabling redirects for clients that should not follow them, validating the response’s origin, and setting timeouts to prevent hanging connections. In environments that rely on service discovery or secrets, ensure that credentials are not exposed through SSRF-reachable endpoints.
middleBrick’s LLM/AI Security checks are relevant when FastAPI endpoints interact with AI services or expose prompts. The scanner checks for system prompt leakage and active prompt injection attempts, which can be particularly impactful if SSRF is combined with an LLM endpoint that processes attacker-controlled input.