September 20, 2026
SSRF: The Complete Interview-Ready Breakdown (and Why the Standard Defense Keeps Losing)
Part of my Application Security Fundamentals series.
By Prianshu Bhaskar
4 min read
Server-Side Request Forgery (SSRF) is a vulnerability where an attacker manipulates a server into making an HTTP (or other protocol) request to a destination the attacker chooses, rather than the destination the application intended. The request comes from the server, using the server's network position and trust โ not from the attacker's own machine.
Two conditions have to both be true for SSRF to exist:
- The application makes an outbound request based on user-supplied or user-influenced input (a URL, a hostname, sometimes just a path fragment).
- The server making that request has network access to something the attacker wants but can't reach directly โ an internal admin panel, an internal API, a database interface, or a cloud metadata endpoint.
If either condition is missing, there's no SSRF โ either the destination is server-picked and never varies, or the server has no interesting internal network access to abuse.
Types of SSRF
1. Regular / In-Band SSRF
The response to the forged request is returned to the attacker in the same channel โ visible directly in the application's own response.
Example: a "check item availability" feature takes a backend API URL as a parameter and displays whatever that API returns. If an attacker swaps that URL for an internal address, the internal service's response gets rendered right back to them on the page.
2. Blind / Out-of-Band SSRF
The forged request happens, but its response is not returned to the attacker anywhere they can see. The application makes the request server-side and moves on, giving no visible confirmation.
Example: a webhook-validation feature "pings" a URL to check it's reachable, but only ever shows "valid" or "invalid" โ never the actual response body.
Blind SSRF is harder to detect but far from harmless. Two common techniques attackers use to confirm and exploit it:
- Out-of-band interaction: point the forged request at a domain the attacker controls and monitor DNS/HTTP logs on their own server. If a request lands, the SSRF is confirmed โ even with zero visible response.
- Time-based / side-channel confirmation: if response content isn't visible but response time differs (a fast response for open ports, a timeout for closed ones), an attacker can still map internal infrastructure purely from timing.
Impact โ What You Get If It Works
- Internal network reconnaissance โ port-scanning and mapping internal services the server can reach, that the internet can't
- Unauthorized access to internal-only systems โ admin panels, internal dashboards, databases with no external auth layer because "it's internal"
- Cloud credential theft โ reaching the cloud provider's instance metadata endpoint and extracting temporary IAM credentials (covered in depth below โ this is usually the highest-value outcome)
- Remote code execution โ in specific cases, chaining SSRF with a vulnerable internal service (e.g., an internal API that itself has a deserialization or command injection flaw) to go from "reached an internal host" to full compromise
The Bypass Arms Race โ Why Blacklists Keep Losing
Attempt 1: Blacklist the obvious internal addresses
Block localhost, 127.0.0.1, 10.*, 192.168.*. This fails almost immediately because IP addresses have multiple valid representations that all resolve to the same place:
- Decimal:
2130706433=127.0.0.1 - Octal:
0177.0.0.1 - Hex:
0x7f000001 - Shortened:
127.1 - IPv6 loopback:
[::1], or the IPv4-mapped[::ffff:127.0.0.1]
A blacklist built by pattern-matching known-bad strings loses against an input space this large by design, not by implementation mistake.
Attempt 2: Resolve the hostname first, then validate the IP
Stronger โ this closes the encoding loophole, because every representation above resolves to the same canonical IP once you actually resolve it. Still beatable via DNS rebinding / TOCTOU (time-of-check to time-of-use): an attacker's own DNS server answers the validation lookup with a public, harmless IP, then answers a second lookup โ made moments later when the connection actually opens โ with an internal IP instead. The check and the actual connection never used the same resolved address.
Attempt 3: Disable/limit redirects
Someone notices that a "safe," validated URL can still redirect (HTTP 302) to an internal address after validation already passed. Disabling or capping redirects, and re-validating every hop, closes this specific gap.
On AWS, every EC2 instance can reach http://169.254.XXX.254/latest/meta-data/iam/security-credentials/ โ a link-local address that hands back temporary AWS credentials scoped to the instance's IAM role. An SSRF bug that reaches this one address turns a web application flaw into a live cloud account compromise, with real API access, from a single request.
The specific fix: AWS's IMDSv2 requires obtaining a session token via a PUT request before any metadata GET will succeed, and caps the response's network hop limit. This defeats the simple version of the attack, because a typical SSRF only lets an attacker force a simple GET through the vulnerable server โ not a stateful PUT-then-GET exchange. If asked "how do you stop SSRF-to-credential-theft specifically," lead with IMDSv2.
Defense-in-Depth
Application layer:
- Allowlist destination hosts explicitly โ sidesteps the entire encoding arms race by matching a small known-good set instead of trying to exclude an infinite bad one
- Restrict schemes to
http/httpsonly โ rejectfile://,gopher://,dict:// - Resolve the hostname once, validate that specific IP, and connect to that exact IP โ don't allow a second re-resolution at connection time, which closes the DNS-rebinding gap directly
Network/infrastructure layer:
- Block egress from the fetching service to link-local and internal ranges at the firewall/network-policy level, so an application-code bug doesn't automatically become a breach
- Enforce IMDSv2, disable IMDSv1
- Run the URL-fetching service in an isolated network segment with no route to sensitive internal hosts
I write about Application Security and DevSecOps by examining how security controls actually hold up โ and where they quietly don't โ in production. Linkedin: https://www.linkedin.com/in/prianshu-bhaskar/