Server-Side Request Forgery (SSRF)
Server-Side Request Forgery (SSRF) is a flaw where an application fetches a user-supplied URL on the server side, letting an attacker coerce the server into reaching internal services or the cloud metadata endpoint (169.254.169.254) to steal credentials. It maps to OWASP A10:2021 and CWE-918.
A single input field that accepts a URL is enough to turn your own server into an attacker's proxy. SSRF does not break in from the outside; it convinces a trusted machine that already sits behind your firewall to make the request for the attacker, with all of that machine's network reach and identity attached. On cloud-hosted infrastructure, that reach almost always includes the link-local metadata endpoint that hands out short-lived IAM credentials, which is exactly the pivot that turned a misconfigured firewall into the Capital One breach of 106 million records.
Reviewed by Ameya Lambat
Security Research Contributor, Legba
Reviewed 2026-05-28 · Updated 2026-05-28
What it is
SSRF occurs when an application retrieves a remote resource from an address that an attacker can influence, without sufficiently validating that the destination is the one intended. The classic pattern is a feature that fetches a user-supplied URL server-side: a webhook callback, a link-preview generator, a document or image importer, an SSO/OIDC metadata loader, or an API that proxies third-party calls. Because the request originates from the server, it inherits the server's network position and identity. The attacker can substitute internal hostnames, RFC 1918 private addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), loopback (127.0.0.1), or the cloud link-local metadata IP 169.254.169.254. In its strongest form, SSRF reads the response back to the attacker (full-read SSRF); in its blind form, only side effects such as timing or error differences leak information.
What an organization stands to lose here is not abstract. SSRF was the root cause of the 2019 Capital One breach: an attacker abused an SSRF flaw in a misconfigured ModSecurity web application firewall to reach the EC2 Instance Metadata Service (IMDSv1), retrieved the WAF role's temporary IAM credentials, and used the over-privileged role to list and exfiltrate roughly 30 GB of data on about 106 million credit-card applicants, as documented by Krebs on Security and the AWS Security Blog. OWASP added SSRF to the Top 10 in 2021 specifically because the move to cloud architectures made the metadata-credential pivot routine. The job your team actually wants done is to know, with evidence, whether any externally reachable endpoint can be coerced into that pivot before someone else demonstrates it for you. Left open, SSRF converts a low-noise web request into credential theft, lateral movement, internal port scanning, and in many stacks remote code execution.
At a glance
How attackers find and exploit it
- Map externally reachable endpoints and crawl for any parameter, header, or JSON field that accepts a URL, hostname, or IP, such as url=, image=, callback, webhook, feed, or proxy fields, and SSO/metadata import endpoints.
- Point the parameter at an attacker-controlled collaborator host (e.g. an out-of-band interaction listener) and watch for an inbound DNS lookup or HTTP request from the target's egress IP, confirming the server fetches the supplied address.
- Pivot the destination to internal and link-local ranges (127.0.0.1, 10.0.0.0/8, 169.254.169.254) and compare response sizes, status codes, and timing to enumerate reachable internal services even when responses are not returned (blind SSRF).
- On cloud workloads, request the metadata endpoint to harvest IAM credentials, for example http://169.254.169.254/latest/meta-data/iam/security-credentials/ on AWS IMDSv1, or the equivalent Azure (with Metadata: true header) and GCP (Metadata-Flavor: Google header) paths.
- Bypass naive deny lists using alternate IP encodings (decimal, octal, hex, IPv6-mapped), DNS rebinding, redirect chains (302 to an internal host), and shorthand such as http://0/ or http://[::]/ to defeat string-based filters.
- Use the harvested credentials or internal access to reach databases, object storage, admin panels, or other services, escalating to data exfiltration, lateral movement, or remote code execution against unauthenticated internal endpoints.
How to detect it on your surface
- Inventory every feature that fetches a remote resource server-side: webhooks, link previews, file/URL importers, PDF and screenshot renderers, OIDC/SAML metadata loaders, and any API that proxies outbound calls.
- For each, test whether a supplied URL triggers an outbound request from your server by pointing it at an out-of-band listener and confirming the inbound hit comes from your infrastructure's egress address.
- Probe whether internal and link-local destinations are reachable from the application tier: attempt 127.0.0.1, an internal hostname, and 169.254.169.254, and observe differences in response code, body, or latency.
- Check whether cloud instances enforce IMDSv2 (session-token required, hop limit 1) or still permit IMDSv1 request/response metadata access from the workload.
- Review egress firewall and security-group rules to determine whether the application tier can open arbitrary outbound connections rather than only allowlisted destinations and ports.
Detection signals
- An inbound DNS resolution or HTTP request arriving at an out-of-band collaborator host that originates from the target application's known egress IP shortly after a crafted URL is submitted.
- Differential responses across destinations: a connection-refused or timeout for a closed internal port versus a 200/redirect or distinct latency for an open one, revealing internal service enumeration.
- Metadata-shaped content echoed in a response or error, such as JSON containing AccessKeyId, SecretAccessKey, and Token fields, or directory listings under /latest/meta-data/.
- Server-side fetch errors that leak internal context in stack traces or messages, for example 'Connection refused to 10.x.x.x' or DNS resolution errors for internal-only hostnames.
- WAF/proxy access logs showing outbound requests to 169.254.169.254 or RFC 1918 addresses sourced from a component that should only call external partner APIs.
Validate before you report
- Confirm the outbound request is genuinely server-side, not browser-side, by verifying the inbound interaction at a controlled listener originates from the server's egress IP rather than the tester's client.
- Demonstrate that an internal or link-local destination is actually reachable (not merely accepted by the parser) by retrieving a distinguishing response, header, or measurable timing difference tied to that destination.
- Capture concrete evidence: the request that triggered the fetch, the responding host/IP, and any returned content such as internal banners or metadata fields, redacting live secrets while proving access.
- Determine read capability: classify the finding as full-read SSRF (response returned to attacker) versus blind SSRF (only side effects observable), since this drives severity and exploitability.
- For cloud targets, verify whether the metadata path returns credentials (IMDSv1 enabled) or is blocked by IMDSv2 enforcement, establishing whether the credential-theft pivot is live.
What looks like this but isn't
- An intended outbound integration: the endpoint is supposed to fetch external partner URLs, the destination is restricted to a strict allowlist, and internal/link-local addresses are rejected, so coercion to an unintended host is not possible.
- A reflected error or open-redirect that never causes a server-side fetch; the response merely echoes the URL or redirects the client, with no request originating from your infrastructure when tested against an out-of-band listener.
- Metadata access that is already neutralized: the path resolves but IMDSv2 enforcement (session token plus hop limit 1) blocks credential retrieval, so the apparent reachability does not yield usable secrets.
Remediation
- Validate destinations with a strict allowlist of permitted domains and IP addresses using exact, case-sensitive matching, and reject anything not on the list rather than relying on deny lists that filters trivially bypass.
- Resolve the hostname yourself, validate the resulting IP against the allowlist, and connect to that validated IP to defeat DNS rebinding and time-of-check/time-of-use tricks; disable or strictly validate HTTP redirects.
- Block requests to internal, loopback, and link-local ranges at the application layer (RFC 1918, 127.0.0.0/8, 169.254.0.0/16, ::1, IPv4-mapped IPv6), and reject non-HTTP(S) schemes such as file://, gopher://, and dict://.
- Enforce IMDSv2 on all cloud instances (require the session token and set the metadata hop limit to 1), and apply least-privilege IAM so a coerced workload cannot reach sensitive data even if it reaches the metadata service.
- Apply network-layer egress controls: place fetcher components in a segmented network, deny outbound by default, and allow only the specific destinations and ports the feature legitimately needs.
- Send a minimal, non-raw response back to the client (do not return the raw fetched body), disable verbose error messages, and add authentication on internal services so they are not reachable unauthenticated even from inside.
Operational checklist
- Maintain an inventory of every server-side URL-fetching feature and require a documented destination allowlist for each before it ships.
- Enforce IMDSv2 organization-wide as a standing guardrail and continuously detect any instance still permitting IMDSv1.
- Default-deny outbound network egress for application tiers and review allowlist exceptions on a regular cadence.
- Include SSRF test cases (internal IPs, link-local metadata, alternate IP encodings, redirects, DNS rebinding) in CI security testing and pre-release reviews.
- Audit IAM roles attached to internet-facing components for least privilege so a successful SSRF yields minimal blast radius.
- Monitor egress and proxy logs for requests to 169.254.169.254 and private ranges from components that should only call external partners, and alert on anomalies.
What to do next
SSRF is the difference between a web request and a stolen identity: the same flaw that let Capital One's WAF be turned into a credential-harvesting proxy lives in any feature that fetches a URL on your behalf. The concrete next step is to enumerate those features on your external surface, prove whether each can reach 169.254.169.254 or an internal service, and shut the path before someone else uses it. Treat a validated, evidenced SSRF finding as an emergency: enforce IMDSv2, allowlist destinations, and lock down egress now rather than after exfiltration.
Methodology
Each finding-type guide is built from Legba Recon's real detection and validation logic, reviewed by a named security contributor, and cited against primary sources such as OWASP, CISA, NIST, and MITRE. We update pages when the underlying guidance changes. See our contributors and company.
FAQs.
References.
- 01
- 02
- 03Server Side Request Forgery Prevention Cheat SheetOWASP Cheat Sheet Series
- 04
- 05What We Can Learn from the Capital One HackKrebs on Security
