Back to glossary

Server-side request forgery (SSRF)

8 min read

In web and cloud security, server-side request forgery (SSRF) is a flaw where an attacker makes the application send an HTTP request of their choosing from its own network position. The request arrives with the server’s source address and its credentials, so it reaches internal services that were never meant to be exposed.

July 29, 2026
Compartir:

How it works

Applications fetch things. They render a preview of a link, import a document from a URL, call a webhook the customer configured, check an image, or proxy a request to a back end. Wherever the destination of that fetch is influenced by user input, the user can point it somewhere else.

The value of that is not the response. It is the position. The application sits inside the network perimeter, often inside a private subnet, with a source address that internal services trust and with credentials attached to its runtime. A request from the internet to an internal administrative interface is refused at the edge. The same request made by the application is a request from a trusted host.

The classic target is a service that binds to loopback or to a private range and has no authentication of its own, because whoever deployed it reasoned that the network was the control. Internal dashboards, message queues, caches, container orchestration APIs and metrics endpoints all fall into that pattern.

In the cloud the target is more specific and more valuable: the instance metadata service, a link-local HTTP endpoint that every workload can reach and that hands out temporary credentials for the role the workload runs as. If the endpoint responds to a plain unauthenticated GET, an SSRF in a preview feature becomes a set of valid cloud credentials, and from there the engagement moves from the application to the account.

Blind SSRF is the case where the response never comes back. It is still exploitable: the request either happens or it does not, and that yes or no is enough to map an internal range, and enough to trigger a state-changing request against a service that does not need to answer.

What goes wrong

The most common failure is a validation that checks the string instead of the destination. A filter looks at the hostname, decides it is not internal, and the application then resolves that name to a private address. Names are attacker-controlled, DNS answers are attacker-controlled, and redirects are attacker-controlled: a permitted host returning a redirect to an internal address defeats a check performed only on the original URL.

The second failure is validating once and connecting later. Between the check and the socket there is a second DNS lookup, and an attacker who controls the zone can answer differently each time. The fix is not a better regular expression; it is resolving the name yourself, checking the address you resolved, and connecting to that address.

The third is where SSRF earns its place in a pentest. On its own it is a request from a server. The finding we write is almost never that. It is the chain: an image preview accepts a URL, the URL reaches the metadata endpoint, the endpoint returns credentials for the instance role, the role has read access to a storage bucket that was never meant to be reachable from the web tier, and the bucket holds customer documents. Each link is a low or medium severity issue in isolation. Together they are the report. Chasing the whole chain rather than stopping at “the server made a request” is what separates a real test from a scanner result.

SSRF and CSRF are different attacks

The names look alike and they are confused constantly, including in remediation tickets that then apply the wrong fix. The forged request comes from opposite sides.

SSRF CSRF
Who sends the request The server The victim’s browser
Whose position is abused The application’s network location and role The victim’s authenticated session
What the attacker reads Often the response, sometimes nothing Nothing, by design
Typical target Internal services, cloud metadata, back ends State-changing endpoints in the same application
The fix Resolve and check the destination address, egress control Anti-CSRF tokens, SameSite cookies

The consequence for a defender is that anti-CSRF tokens do nothing about SSRF, and outbound network controls do nothing about cross-site request forgery. Two names, two layers, no overlap.

Common mistakes

Blocking a list of private ranges by string match. Addresses can be written in decimal, in octal, with IPv6 mapping, or hidden behind a name that resolves to them. Match on the resolved address, in binary, against the ranges you mean.

Forgetting the redirect. If the fetch follows redirects, every check must be repeated at every hop. In practice, disable redirect following on server-side fetches or re-validate each one.

Assuming a blind case is harmless. A request that returns nothing still reaches a queue, still triggers a webhook, still deletes something on a REST API that accepts a GET where it should not. Absence of a response is not absence of impact.

Treating metadata protection as a network problem. The link-local endpoint cannot be firewalled away from the workload, because the workload legitimately uses it. The control is at the endpoint: require a session-oriented request, and set the response hop limit so a forwarded request from a container does not reach it.

Fixing the one parameter we reported. SSRF is a property of every place the application fetches a URL. If the import feature was fixed and the webhook validator was not, nothing changed.

How to reduce it

Start by deciding whether the destination needs to be open at all. Most fetch features have a small set of legitimate targets, and an allow-list of hosts is both simpler and stronger than any filter. Where the destination is genuinely arbitrary, resolve the name in your own code, reject any address in a private, loopback, link-local or reserved range, and connect to the address you validated rather than to the name.

Push the fetch away from the sensitive position. A dedicated egress proxy, or a small service in a subnet with no route to anything internal, turns a successful SSRF into a request that reaches nothing. Apply egress filtering so the application can only reach the destinations it needs, which is usually a very short list and almost never “the internet”.

In cloud, enforce the session-oriented metadata mode across the estate rather than per instance, because one workload left on the old mode is the one that will be found. Then reduce what the role is worth: a web tier role scoped to the two buckets it uses turns credential theft into a significantly smaller incident. That scoping is least privilege applied to a machine identity rather than a person.

For detection, the signal is in egress logs and DNS: an application host resolving names it has never resolved before, requests to link-local addresses, or a burst of connection attempts across a private range from a host that normally talks to three destinations.

Where this shows up in an audit

In a report, SSRF is written against the parameter that controls the destination, and the finding carries the chain, not just the primitive. We record the request, the internal destination reached, what came back, and where the chain stopped. If it reached credentials, we say which identity was issued, what it was scoped to, and what we confirmed we could reach with it. We stop at the first piece of evidence that proves the reach, and we do not exercise the credential further than needed to establish it.

Severity is decided by where the request landed, never by the existence of the flaw. An SSRF that can only reach the public internet is a low finding written for completeness. One that reaches a metadata endpoint on an unversioned configuration is critical before anyone opens a console, because the next step is a cloud attack path rather than another web request.

This is a fixed part of how we approach an application that fetches things, and it is the finding that most often moves an engagement from the application into the cloud account.

FAQ

What can an attacker actually do with SSRF? Reach anything the server can reach: internal admin interfaces with no authentication, cloud metadata and its credentials, container and orchestration APIs, internal APIs that trust the source network, and, where a redirect or protocol handler is available, services that are not HTTP at all.

Does a firewall stop SSRF? Not at the perimeter, because the request originates inside it. Outbound filtering does help, because it decides where the forged request is allowed to go, and it is one of the few controls that reduces impact without touching the application.

Is SSRF the same as an open redirect? No. An open redirect sends the user’s browser somewhere; SSRF sends the server. They combine, though: an open redirect on a permitted host is a common way to bypass an SSRF allow-list.

How do we protect the cloud metadata endpoint? Require the session-oriented request mode everywhere, set the response hop limit so requests forwarded from inside a container do not reach it, and reduce the permissions on the instance role so that a leaked credential is worth less.

¿Quieres ver cómo trabajamos en Asperis Security?

Agenda 30 minutos con uno de nuestros especialistas. Revisamos tu stack y te decimos qué conviene probar primero.