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.
# 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).contentValidating 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
1. What is the core mechanism that makes SSRF dangerous?
2. What made the 2019 Capital One breach notable as an SSRF example?
3. Why is hostname-only URL validation insufficient to prevent SSRF?
4. How can blind SSRF be detected when the application never returns the response body?
5. What specific protection does AWS IMDSv2 add compared to IMDSv1?
Was this page helpful?
You May Also Like
Insecure Deserialization
Learn how deserializing untrusted data can lead to remote code execution, object injection, and denial of service, and how to safely handle serialized data.
Sensitive Data Exposure
Understand how sensitive data like passwords, tokens, and PII leak through weak cryptography, misconfigured storage, and insecure transport, and how to prevent it.
Vulnerable and Outdated Components
Understand the risks of using outdated or vulnerable third-party libraries, frameworks, and dependencies, and how to manage them securely.