SSRF Borrows Your Server's Network Position, and Validating the Hostname Does Not Help
The Capital One breach was 100 million records from one server-side request. The reason the obvious fix fails is subtler than a bad blocklist: you check a hostname, then you resolve it again to make the request, and DNS is free to answer differently the second time.

Key takeaways
- Server-side request forgery works by making your server issue an attacker-chosen request, which borrows the network position and credentials your server has and the attacker does not.
- The Capital One breach exposed more than 100 million records through a single SSRF request that retrieved overprivileged credentials from the cloud metadata service.
- DNS rebinding defeats both blocklists and allowlists that validate at submission time, because the attacker's domain can resolve to an allowed address during validation and to their own address when the request is actually made.
- The fix for that gap is to resolve the hostname once, check the resulting IP address against your rules, and then request that exact IP, rather than validating a name and resolving it again later.
- IMDSv2 requires a session token obtained via a PUT request and enforces a hop limit, which breaks most naive SSRF attempts against cloud metadata, and disabling IMDSv1 so that v2 is enforced is the single highest-impact fix.
- A complete defence combines a default-deny egress posture, a hardened URL validator, and IMDSv2 enforcement on every cloud workload that makes outbound requests.
SSRF sounds like a minor input-validation issue. It produced the Capital One breach: more than 100 million records, from a single server-side request that retrieved overprivileged credentials from the cloud metadata service.[1]
The reason it is that severe is worth stating precisely, because it explains why the obvious defences fail. An attacker on the internet cannot reach your internal services and does not hold your credentials. Your server can and does. SSRF is not really about a URL parameter; it is about borrowing your server's position. Every request it makes on the attacker's behalf is made with your network access and your identity.
“The attacker is not attacking your server. They are using it, because it can reach things they cannot and carries credentials they do not have.”
Why Blocking Internal Addresses Fails
The intuitive fix is a blocklist: reject anything pointing at localhost, private ranges, or the metadata address. It does not work, and the reason is more interesting than the usual explanation about encoding tricks.
Validating the URL and making the request are two separate DNS resolutions. You resolve the hostname to check it. Later, your HTTP client resolves it again to connect. Nothing guarantees those two lookups return the same answer.
DNS rebinding exploits exactly that. The attacker controls a domain and sets a very short TTL, so it resolves to a permitted address while you are validating and to an internal address when the request actually goes out.[2] Your check passed. It passed against a value that no longer applies.
And note this defeats allowlistsas well: the attacker's domain resolves to an allowed IP on the first lookup and to their chosen IP on the second.[2] An allowlist is much better than a blocklist, and it is not sufficient if what you are allowlisting is a name. Why DNS is free to behave this way is a consequence of how resolution and TTLs work, covered in what DNS actually does.
Why this matters
The Fix That Actually Closes It
Resolve once, check the address, request the address.[2]
Concretely: resolve the hostname to an IP yourself. Validate that IP against your rules. Then make the request to that exact IP rather than handing the hostname back to your HTTP client and letting it resolve again. The window the attack needs disappears, because there is no second lookup to poison.
Two things that still need handling once you have done that:
Redirects. An allowed host can respond with a 302 to anywhere. If your client follows redirects automatically, your careful validation covered only the first hop. Either disable following, or re-validate each hop with the same resolve-then-check discipline.
Default-deny egress. The most robust layer is not in your code at all. If the workload can only reach the handful of destinations it genuinely needs, an SSRF bug has nowhere useful to point.[3] This is the same argument as enumerating an agent sandbox's egress paths, and it is the same lesson from the OpenAI agent escape, which left through the one outbound path its environment had to trust. Outbound is where these failures live and it is the direction nobody inspects.
IMDSv2 Is the Cheapest Big Win
The reason SSRF became critical rather than merely awkward is the cloud metadata service. An unauthenticated HTTP endpoint, reachable from the instance, that hands out credentials. Any SSRF becomes credential theft.
IMDSv2 changes the shape of that endpoint. A caller must first obtain a session token with a PUT request, then present it on subsequent calls, and a hop limit prevents the request being proxied.[3]
Both requirements are hard for an SSRF to satisfy. Most SSRF primitives give an attacker a GET to a URL of their choice, not the ability to issue a PUT, capture the response header, and replay it. So enforcing v2, which specifically means disabling v1, breaks most naive metadata attacks outright and is described as the single highest-impact fix available.[3]
Worth being precise about the wording: enabling v2 while leaving v1 available achieves nothing, because the attacker simply uses v1. The change that matters is turning v1 off.
What I Would Do, In Order
Enforce IMDSv2 everywhere and disable v1. Configuration change, no code, removes the worst outcome. Do this first regardless of whether you think you have an SSRF.
Default-deny egress on anything that fetches URLs. Then allowlist the specific destinations that feature needs.[3]
Resolve once, validate the IP, request the IP.And handle redirects explicitly rather than inheriting your client's default of following them.
Reduce the credentials the workload holds. Capital One was catastrophic partly because the credentials retrieved were overprivileged.[1] An SSRF that reaches a scoped role with narrow permissions is an incident; one that reaches an over-broad role is a breach. That is an authorization problem rather than a network one, which is where the OWASP API list keeps pointing.
Takeaway
SSRF matters because it borrows your server's network position and credentials, not because a URL was malformed. Blocklists and even allowlists fail when they validate a hostname, since the name is resolved again to make the request and DNS may answer differently, which is a time-of-check to time-of-use bug rather than an encoding one. Resolve once and request the IP you checked, handle redirects deliberately, deny egress by default, and enforce IMDSv2 by disabling v1, which is the cheapest large reduction in blast radius available.
Sources and further reading
- 1.Reporting"What is SSRF (server-side request forgery)?". Source for the Capital One breach exposing over 100 million records via a single SSRF request retrieving overprivileged credentials from the metadata service.
- 2.Reporting"How DNS rebinding turns SSRF into a cloud takeover". Source for rebinding defeating both blocklists and allowlists that validate at submission time, and for the resolve-then-request-the-IP mitigation that closes the gap.
- 3.Reporting"SSRF prevention guide". Source for IMDSv2 requiring a PUT-issued session token and enforcing a hop limit, for disabling IMDSv1 being the highest-impact fix, and for combining default-deny egress with a hardened URL validator.
- 4.PrimaryOWASP, "Server Side Request Forgery Prevention Cheat Sheet". The reference implementation guidance, including the case distinction between fetching from a known allowlist and accepting arbitrary user-supplied destinations.
Frequently asked questions
- What is SSRF?
- Server-side request forgery is when an attacker induces your server to make an HTTP request to a destination of their choosing. The value to them is not the request itself but the position it is made from, since your server sits inside your network and carries credentials that an attacker on the internet does not have.
- Why is SSRF considered so severe?
- Because it converts an input-handling bug into access to internal infrastructure. The Capital One breach exposed over 100 million records through a single SSRF request that retrieved overprivileged credentials from the cloud metadata service, which is the canonical demonstration that this is not a theoretical severity rating.
- Why does blocking internal IP addresses not stop SSRF?
- Because validating a hostname and making the request are two separate resolutions, and DNS can answer differently each time. In a DNS rebinding attack the attacker's domain resolves to a permitted address while you are validating, then to an internal address when your server actually connects, so your check passed against a value that no longer applies.
- Does an allowlist prevent SSRF?
- An allowlist is much better than a blocklist and is still bypassable if it validates a name rather than an address. DNS rebinding works against allowlists too, since the attacker's domain can resolve to an allowed IP on the first lookup and to their chosen IP on the second, so the allowlist has to be applied to a resolved address rather than to a hostname.
- How do you actually fix the DNS rebinding gap?
- Resolve the hostname to an IP address once, check that specific address against your rules, and then make the request to that address directly instead of re-resolving the name. That removes the window between the check and the use, which is what the attack depends on.
- What is IMDSv2 and why does it matter?
- It is the session-oriented version of the cloud instance metadata service: a caller must first obtain a token with a PUT request and then present it, and a hop limit prevents the request being proxied. Those two requirements break most naive SSRF-to-metadata attempts, because a simple attacker-controlled GET can do neither, so enforcing v2 and disabling v1 is the highest-impact single change available.
Written by
Tech Talk News Editorial
Computer engineering background. Writes about software, AI, markets, and real estate, and the places where the three meet.
More about the author