Server-side request forgery happens when server code makes an outbound HTTP request to a destination that a user fully or partially controls. The danger isn't the request itself — it's that the request originates from inside your infrastructure, with your server's network position and sometimes its credentials, letting an attacker use your own backend as a proxy into places the public internet was never supposed to reach.
Where SSRF hides in ordinary features
- Webhook URL fields — anywhere a user configures a URL that your server will later call.
- "Import from URL" or link-preview and unfurling features that fetch a page to extract a title, image, or metadata.
- PDF or image generation that renders a user-supplied URL server-side.
- Logo or avatar fetching during signup or OAuth flows, where a URL is pulled from an external profile.
- Any server-side rendering step that resolves a link the user provided before displaying it.
Why cloud metadata endpoints raise the stakes
Most cloud providers expose an instance metadata service at a fixed link-local address (commonly 169.254.169.254) that hands back information about the running instance — and, in misconfigured setups, temporary credentials for whatever role the instance runs as. If server-side code can be tricked into making a request to that address, SSRF stops being an information-disclosure curiosity and becomes a path to full credential theft and lateral movement inside the cloud account. This single fact is why SSRF is treated far more seriously today than its description — "the server fetched a URL it shouldn't have" — might initially suggest.
Blocklists are the wrong control
Checking a user-supplied URL against a list of forbidden strings like localhost or 127.0.0.1feels like a fix and isn't one. Attackers route around it with alternate IP encodings (decimal, octal, or IPv6-mapped forms of a loopback address), DNS names that resolve to an internal address only at request time (DNS rebinding), and redirects — a URL that passes validation, then responds with a redirect to an internal address that the HTTP client follows without re-checking.
What a real fix looks like
- Validate against an explicit allow list of expected hosts wherever the set of legitimate destinations is known in advance, rather than trying to block everything bad.
- Resolve the DNS name and check the resulting IP address is not in a private, loopback, or link-local range before opening the connection — checking the hostname string alone is not enough.
- Disable automatic redirect-following on outbound requests, or re-validate the destination after every redirect hop rather than trusting the first check.
- Add network-level egress restrictions as defense in depth, so that even a missed case in application code can't reach internal services or the metadata endpoint.
Checklist for reviewing code that makes outbound requests
- Every server-side fetch, image download, or webhook delivery that uses a user-supplied URL is traced end to end for validation.
- Validation happens against the resolved IP address, not just the hostname string.
- Redirects are either disabled or re-validated on each hop.
- Features that don't need to support arbitrary destinations use an allow list instead of a blocklist.