100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Security

SSRF Explained

Learn how Server-Side Request Forgery lets attackers trick a server into making unauthorized requests to internal systems, and how to prevent it.

Data & DependenciesAdvanced9 min readJul 10, 2026
Analogies

What SSRF Is and Why It Matters

Server-Side Request Forgery (SSRF) occurs when an attacker manipulates a server-side application into making HTTP (or other protocol) requests to an unintended destination, exploiting the server's own network position and trust rather than the attacker's own network access. A classic example is a 'fetch image from URL' or 'import from a webhook' feature: instead of a legitimate external URL, the attacker supplies http://169.254.169.254/latest/meta-data/ (the cloud metadata endpoint) or an internal address like http://10.0.0.5:8080/admin, and the server — sitting inside the trusted internal network — dutifully makes that request and often returns the response to the attacker, effectively turning the server into a proxy for reaching resources the attacker could never reach directly.

🏏

Cricket analogy: It is like a fan tricking the team's official courier into hand-delivering a request straight into the dressing room using the team's own trusted access badge, rather than trying to sneak in themselves.

Common SSRF Targets: Cloud Metadata and Internal Services

The single most exploited SSRF target is the cloud provider instance metadata service, historically reachable at the well-known link-local address 169.254.169.254 without any authentication in AWS's original IMDSv1, which can return temporary IAM credentials that the compromised server's role has been granted — this exact technique was central to the 2019 Capital One breach, where an SSRF vulnerability in a misconfigured WAF let the attacker retrieve S3 credentials and exfiltrate over 100 million customer records. Beyond cloud metadata, SSRF is used to port-scan and reach internal-only services (databases, admin panels, internal APIs, Kubernetes dashboards) that have no direct internet exposure specifically because they trust anything originating from inside the network perimeter.

🏏

Cricket analogy: It is like discovering a side gate at the stadium that only requires you to be 'inside the perimeter fence' to pass, with no ticket check, letting anyone who gets past the outer wall walk freely to the players' area.

Blind SSRF and Protocol Smuggling

Not all SSRF gives the attacker a direct response to read; 'blind' SSRF occurs when the server makes the request but the response is never shown back to the attacker, in which case impact is inferred through timing differences, out-of-band DNS/HTTP callbacks to an attacker-controlled server, or side effects (like triggering an internal action). SSRF payloads can also abuse alternate URL schemes and protocol handlers — file://, gopher://, dict://, or even redirects and DNS rebinding that resolve a seemingly external hostname to an internal IP after the initial validation check passes — to bypass naive allowlist/blocklist filters that only inspect the literal string of the submitted URL.

🏏

Cricket analogy: Blind SSRF is like a spectator who can't see inside the dressing room but infers a wicket fell purely from the crowd's roar timing, gathering intelligence indirectly without ever seeing the direct result.

python
# Bad: fetching a user-supplied URL with no validation
import requests
def fetch_preview(url):
    return requests.get(url, timeout=5).content  # SSRF: attacker can supply internal/metadata URLs

# Better: resolve, validate against an allowlist, and block private/link-local ranges
import ipaddress
import socket
from urllib.parse import urlparse

ALLOWED_SCHEMES = {"http", "https"}
BLOCKED_NETWORKS = [ipaddress.ip_network(cidr) for cidr in (
    "127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",
    "169.254.0.0/16", "::1/128", "fc00::/7"
)]

def is_safe_url(url):
    parsed = urlparse(url)
    if parsed.scheme not in ALLOWED_SCHEMES:
        return False
    try:
        resolved_ip = ipaddress.ip_address(socket.gethostbyname(parsed.hostname))
    except (socket.gaierror, ValueError):
        return False
    return not any(resolved_ip in net for net in BLOCKED_NETWORKS)

def fetch_preview(url):
    if not is_safe_url(url):
        raise ValueError("URL resolves to a disallowed network")
    return requests.get(url, timeout=5, allow_redirects=False).content

Validating a URL's hostname alone is insufficient — DNS rebinding attacks resolve an attacker-controlled hostname to a safe IP during validation, then to an internal IP at request time. Always resolve and re-validate the IP immediately before connecting (or use a network-layer control), disable automatic redirect-following, and prefer an explicit outbound allowlist over a blocklist wherever feasible.

Preventing SSRF in Depth

Effective SSRF prevention layers multiple controls: at the application layer, validate and allowlist destination hosts/schemes rather than trying to blocklist every dangerous address, disable HTTP redirect-following on outbound requests (or re-validate after each redirect), and resolve DNS just before connecting rather than trusting an earlier lookup. At the infrastructure layer, upgrade cloud metadata services to require a session token (AWS IMDSv2 mandates a PUT-based token handshake that plain SSRF requests can't perform), place outbound-request-making services in a network segment with strict egress firewall rules that block access to internal IP ranges, and run any URL-fetching functionality through a dedicated proxy that enforces these policies centrally rather than relying on every application to implement it correctly.

🏏

Cricket analogy: Requiring IMDSv2-style token handshakes is like a ground requiring a two-step biometric plus PIN check for pavilion access instead of just checking that you're standing inside the boundary rope, closing the loophole simple presence exploited.

AWS's IMDSv2 requires a PUT request to obtain a session token before any metadata can be read via GET, and by default that PUT request has a low TTL and cannot easily be performed through a typical SSRF vector that only controls a GET request's URL — a direct infrastructure-level mitigation informed by real incidents like Capital One's.

  • SSRF tricks a server into making requests to unintended destinations, exploiting the server's own trusted network position.
  • Cloud metadata endpoints (like 169.254.169.254) are a top SSRF target, as seen in the 2019 Capital One breach.
  • SSRF can also reach internal-only services (databases, admin panels, internal APIs) that trust anything inside the perimeter.
  • Blind SSRF has no visible response, but can be detected via timing side channels or out-of-band DNS/HTTP callbacks.
  • Naive URL validation is bypassable via DNS rebinding, redirects, and alternate schemes like file:// and gopher://.
  • Defense in depth combines allowlisting, disabling redirect-following, re-resolving DNS at connect time, and strict egress firewalls.
  • AWS IMDSv2's token-handshake requirement is a concrete infrastructure-level mitigation against metadata-focused SSRF.

Practice what you learned

Was this page helpful?

Topics covered

#Security#WebSecurityOWASPStudyNotes#CyberSecurity#SSRFExplained#SSRF#Explained#Matters#Common#StudyNotes#SkillVeris