Server-Side Request Forgery (SSRF)
SSRF tricks your server into making HTTP requests to internal infrastructure — cloud metadata endpoints, internal APIs, and services that should never be reachable from the internet.
What Is SSRF?
Server-Side Request Forgery (SSRF) occurs when an attacker can supply a URL that your server fetches on their behalf. The server makes the request from inside your network, bypassing firewalls and accessing resources that are only reachable internally.
SSRF is particularly dangerous in cloud environments, where the metadata service (169.254.169.254) exposes instance credentials with a single HTTP request.
How It Works
A common pattern: a feature that fetches content from a user-supplied URL.
# Vulnerable — user controls the URL
@app.post("/preview")
async def preview(url: str):
response = httpx.get(url) # Attacker passes http://169.254.169.254/...
return response.textAn attacker submits:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
The server returns AWS IAM credentials — giving the attacker full cloud access with the permissions of the EC2 instance.
Other internal targets:
http://localhost:6379 # Redis (no auth by default)
http://10.0.0.1/admin # Internal admin panel
http://kubernetes.default # Kubernetes API server
Real-World Impact
- Cloud credential theft — AWS/GCP/Azure metadata leaks IAM keys
- Internal service access — reach databases, admin panels, message queues
- Port scanning — enumerate internal network topology
- Remote code execution — chains with other vulnerabilities on internal services
SSRF was the root cause of the 2019 Capital One breach, exposing 100M+ customer records.
How to Fix
Allowlist approach (strongly preferred):
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.example.com", "cdn.example.com"}
def safe_fetch(url: str) -> bytes:
parsed = urlparse(url)
if parsed.hostname not in ALLOWED_HOSTS:
raise ValueError(f"Host not allowed: {parsed.hostname}")
if parsed.scheme not in ("http", "https"):
raise ValueError("Only HTTP/S allowed")
return httpx.get(url).contentBlock internal ranges (defense in depth):
import ipaddress
BLOCKED = [
ipaddress.ip_network("169.254.0.0/16"), # Link-local / cloud metadata
ipaddress.ip_network("10.0.0.0/8"),
ipaddress.ip_network("172.16.0.0/12"),
ipaddress.ip_network("192.168.0.0/16"),
ipaddress.ip_network("127.0.0.0/8"),
]Disable redirects — attackers use open redirects to bypass allowlists:
httpx.get(url, follow_redirects=False)What VibeWShield Detects
VibeWShield tests URL-accepting endpoints with SSRF payloads targeting cloud metadata endpoints (169.254.169.254), localhost, and internal RFC-1918 ranges. It also checks for DNS rebinding vectors and file:// scheme access.
Free security scan
Test your app for Server-Side Request Forgery (SSRF)
VibeWShield automatically checks for Server-Side Request Forgery (SSRF) and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.
Scan your app free