Server side request forgery, or SSRF, is a bug where an attacker makes your server send requests on their behalf. The user controls a URL, the server fetches it, and suddenly the server is knocking on doors the user could never reach directly. This post explains how server side request forgery works, why it is so dangerous in the cloud, how to spot it, and how to shut it down. The examples use a made up app so nothing here points at a real target.
If you want the one line version first: any feature that takes a URL or address from a user and fetches it is a place SSRF can hide.
What server side request forgery actually is
Picture an app called Acme Notes. It has a friendly feature: paste a link and it pulls a preview image for you. Behind the scenes the server does something like this.
POST /preview
{ "url": "https://example.com/photo.png" }
The server reads that URL, makes the request itself, and sends the result back. That is the whole feature, and on a good day it is harmless. The problem is the server will fetch whatever you put there, including addresses that belong to the inside of the network, not the public internet.
So an attacker stops sending a normal photo link and starts sending internal ones.
POST /preview
{ "url": "http://localhost:8080/admin" }
POST /preview
{ "url": "http://192.168.0.10/" }
Your server happily reaches those, because to the network the request is coming from a trusted machine, not from a stranger. The user could never open http://localhost:8080/admin in their own browser. The server can, and you just lent it to them.
Why SSRF is so dangerous in the cloud
On a normal server SSRF lets an attacker map and poke at internal services: admin panels, databases, message queues, and other apps that were never meant to face the public. In a cloud setup it gets worse, because most cloud providers expose a metadata service at a fixed internal address that hands out configuration and, in some setups, temporary credentials.
If an app is vulnerable and the environment is not locked down, a request aimed at that internal metadata address can return secrets the attacker should never see. From there a small preview feature turns into a path toward the cloud account itself. That is the jump that makes SSRF a headline bug rather than a minor one.
SSRF is rarely about breaking the server. It is about borrowing its position on the network, which is far more powerful than anything the attacker has from outside.
The shapes SSRF shows up in
- Link previews and unfurlers. Anything that fetches a page to show a title or image.
- Webhooks. You let users register a URL to receive events. The server calls it. That is SSRF by design unless you constrain it.
- Document and image processors. Features that import a file from a URL, convert a page to a PDF, or load a remote image.
- Imports by URL. “Import your data from this address” style features.
- Hidden parameters. Fields like
image_url,callback,dest, orfeedburied in a request body.
Some of these are blind, meaning you never see the response. The server still made the request, so an attacker can use timing or out of band tricks to confirm it. Blind does not mean safe.
How to find server side request forgery
Finding SSRF is about reading the app for the assumption it is making. The app assumes the URL you hand it points somewhere public and harmless. So you test that assumption directly.
- List every feature that accepts a URL, host name, or address, including the ones hidden in JSON bodies and headers.
- Point one at an address you control and watch whether the server actually calls it. If it does, the server is fetching user input.
- Then ask the real question: can I aim it at something internal? Try a loopback address, a private range, and the cloud metadata address for your platform.
- For blind cases, use a request listener you own so you can see the server reach out even when the app shows you nothing.
This is the same habit behind most serious findings. You do not throw random payloads. You understand what the feature is for, notice the trust it is built on, and test whether that trust holds. For more on that mindset see how hackers find vulnerabilities.
How to prevent it
You cannot fix SSRF by blocking a list of bad strings, because there are too many ways to write the same address. The fix is to decide, on the server, exactly where a request is allowed to go.
- Use an allow list of destinations. If the feature only ever needs to reach three known providers, allow those and refuse everything else. An allow list beats a block list every time.
- Resolve the host first, then check it. Turn the host name into an IP address and reject anything that lands on a private, loopback, or link local range. Do the check after resolving, so a name that quietly points inside cannot slip through.
- Block the metadata address explicitly and require credentials on that service where your cloud supports it.
- Do not follow redirects blindly. A public URL can redirect to an internal one. Re check the destination on every hop.
- Isolate the fetcher. Run the part that makes outbound requests with no access to internal systems, so even a successful SSRF reaches nothing useful.
The theme is the same as most access control work: the server has to own the decision about what is allowed, not trust the input. If that idea is useful, the web and API security glossary defines SSRF and the terms around it in one place.
Closing
Server side request forgery is a quiet bug. The request looks ordinary, the feature works as designed, and the only thing wrong is where the server is willing to go. That is exactly the kind of assumption an autonomous researcher that studies how an app is meant to work is built to test, by understanding the feature, forming an idea about where the trust breaks, and proving it before calling it a finding. You can read more about UnboundCompute if that approach is interesting.
