The SSRF full form is Server-Side Request Forgery, a web vulnerability where an attacker manipulates a server into making HTTP or other network requests to a destination the attacker chooses. The server becomes a confused proxy: it holds network access and trust that the attacker does not have, and SSRF borrows both. It is common enough that it sits on the OWASP Top 10 as its own category.
Breaking down the full form
Read the name literally and it explains itself:
- Server-Side: the forged request originates from your backend server, not the user's browser. This is what separates SSRF from client-side attacks like CSRF.
- Request: the server makes a network request, usually HTTP, but it can be any protocol the underlying library supports (file, gopher, ftp, and so on).
- Forgery: the destination or content of that request is forged, meaning controlled by the attacker rather than the application.
The core problem is that your server sits inside a trusted network. It can reach internal services, cloud metadata endpoints, and databases that the public internet cannot. When you let user input decide where the server sends a request, you hand the attacker a periscope into that trusted zone.
A concrete example of how SSRF happens
The classic pattern is any feature that fetches a URL the user supplies: a webhook, an image importer, a PDF generator, a link previewer, an avatar-by-URL uploader. Consider a naive image proxy:
# Vulnerable: the server fetches whatever URL the user provides
@app.route("/fetch-image")
def fetch_image():
url = request.args.get("url")
response = requests.get(url) # no validation
return response.content
The developer expected url to be something like https://example.com/cat.png. But nothing stops an attacker from sending:
/fetch-image?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
That address is the cloud instance metadata service. On a misconfigured cloud host it can return temporary IAM credentials, and the server dutifully fetches them and returns the body to the attacker. That single request can escalate to full account compromise. SSRF against metadata endpoints was the mechanism behind several large, well-documented cloud breaches.
Why SSRF is more dangerous in the cloud
Every major cloud provider exposes a link-local metadata endpoint at 169.254.169.254. It hands out instance identity, configuration, and often credentials to anything that can make an HTTP request from the instance. SSRF is the perfect delivery mechanism because the request comes from inside the instance, exactly where the metadata service expects legitimate callers.
Providers responded with hardened metadata services (IMDSv2 on AWS, for example) that require a token obtained via a PUT request, which a simple SSRF cannot perform. Enforcing the hardened version across your fleet is one of the highest-value SSRF mitigations you can apply, and it costs nothing.
Blind SSRF and its uses
Not every SSRF returns the response body to the attacker. In blind SSRF the server makes the request but the attacker never sees the answer. That sounds less useful, but it still lets an attacker:
- Map the internal network by timing which internal IPs respond
- Hit internal admin endpoints that trigger state changes
- Exfiltrate data through DNS or out-of-band channels
Blind SSRF is harder to spot and often gets dismissed as low severity, which is a mistake. Treat any user-controlled outbound request as a potential SSRF regardless of whether the response is visible.
How to prevent SSRF
There is no single flag that fixes SSRF. It is a design problem, and the defenses layer:
Validate against an allowlist, never a denylist. Decide the exact set of hosts your feature legitimately needs to reach and reject everything else. Denylists that try to block 169.254.169.254 or localhost fail against decimal IP encodings, DNS rebinding, and redirects.
from urllib.parse import urlparse
ALLOWED_HOSTS = {"images.example.com", "cdn.example.com"}
def is_allowed(url):
host = urlparse(url).hostname
return host in ALLOWED_HOSTS
Resolve and pin the IP. Resolve the hostname yourself, check that the resulting IP is not in a private or link-local range, and connect to that pinned IP so a DNS rebinding attack cannot swap it after the check.
Disable unneeded URL schemes and redirects. Force https, block file:// and gopher://, and do not follow redirects blindly, because a redirect to 169.254.169.254 sidesteps your initial validation.
Segment the network. Application servers rarely need to reach the metadata endpoint or internal admin panels. Egress firewall rules that block those destinations turn a critical SSRF into a dead end.
Enforce hardened cloud metadata. Require IMDSv2 or the equivalent so a plain GET cannot lift credentials.
Finding SSRF before an attacker does
SSRF surfaces in code review wherever user input flows into an outbound request, and dynamic scanning can probe it by injecting internal and out-of-band URLs into request parameters. A DAST scan can flag endpoints that make server-side requests to attacker-controlled destinations by watching for callbacks to a canary domain. Pair that with a review of every URL-fetching feature, and check whether any vulnerable HTTP client library in your dependency tree contributes to the risk. If you want to go deeper on secure design patterns, the Safeguard Academy covers input validation across attack classes.
FAQ
What does SSRF stand for?
SSRF stands for Server-Side Request Forgery. It is a vulnerability where an attacker causes the server to make network requests to a destination the attacker controls, abusing the server's network position and trust.
How is SSRF different from CSRF?
CSRF (Cross-Site Request Forgery) tricks a user's browser into sending a request. SSRF makes the server itself send the request. The names look similar but the actor and the trust boundary are different.
Why is the address 169.254.169.254 important to SSRF?
That link-local address is the cloud instance metadata endpoint. A successful SSRF can query it to retrieve instance credentials and configuration, which is why so many cloud breaches trace back to SSRF.
Can an allowlist fully prevent SSRF?
A strict allowlist plus IP pinning and blocked redirects gets you most of the way. Combine it with network segmentation and hardened metadata services, because SSRF has enough bypass techniques that no single control is sufficient.