All vulnerabilities
HighA10:2021CWE-918Server-Side

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.text

An 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).content

Block 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.

#ssrf#network#cloud#backend

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