Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy Server-Side Request Forgery (SSRF)
Advanced · 20 min

Server-Side Request Forgery (SSRF)

Understand how attackers use your server as a proxy to access internal services — and how to stop them.

1 What is SSRF?

Server-Side Request Forgery (SSRF) occurs when an attacker can cause the server to make HTTP requests to arbitrary URLs. Because these requests originate from the server, they can reach internal services not exposed to the internet.

# VULNERABLE — fetches URL supplied by user
url = request.form['image_url']
response = requests.get(url)  # Attacker sends: http://169.254.169.254/latest/meta-data/

On AWS, Azure, and GCP, the metadata endpoint (169.254.169.254) returns instance credentials, IAM roles, and startup scripts — all without any authentication. SSRF against cloud metadata can lead to full account takeover.

2 SSRF Defenses

Defense requires validating the URL before making the request AND after resolving DNS (to prevent DNS rebinding):

import socket, ipaddress, urllib.parse

BLOCKED_RANGES = [
    ipaddress.ip_network('169.254.0.0/16'),  # link-local / cloud metadata
    ipaddress.ip_network('10.0.0.0/8'),      # RFC1918 private
    ipaddress.ip_network('172.16.0.0/12'),   # RFC1918 private
    ipaddress.ip_network('192.168.0.0/16'),  # RFC1918 private
    ipaddress.ip_network('127.0.0.0/8'),     # loopback
]

def is_safe_url(url: str) -> bool:
    parsed = urllib.parse.urlparse(url)
    if parsed.scheme not in ('http', 'https'):
        return False
    try:
        ip = ipaddress.ip_address(socket.gethostbyname(parsed.hostname))
        return not any(ip in r for r in BLOCKED_RANGES)
    except Exception:
        return False

3 Architectural Mitigations

Network-level controls are more robust than application-level checks alone:

  • Egress filtering — restrict outbound traffic from the app server to known-good destinations via firewall rules
  • Dedicated fetch proxy — route all outbound HTTP through a proxy that enforces the allowlist; the app itself has no direct internet access
  • AWS IMDSv2 — require session tokens for metadata API requests, mitigating naive SSRF against 169.254.169.254
  • Allowlist domains — if users should only be able to fetch from a known set of CDNs or APIs, maintain a domain allowlist and reject everything else

Defense in depth: combine application-level URL validation with network egress filtering so neither layer alone is a single point of failure.

Knowledge Check

0/3 correct
Q1

Why is SSRF particularly dangerous in cloud environments?

Q2

A developer validates that the URL hostname is not "localhost" before fetching. Why might DNS rebinding still allow an attack?

Q3

Which architectural control provides the strongest SSRF mitigation?

Code Exercise

Add URL Validation Before Fetching

This function fetches a URL provided by the user with no validation — a classic SSRF vulnerability. Add a check that blocks requests to private/loopback IP ranges using the ipaddress module.

python