← Vulnerability class · WebApp Security

Server-Side Request Forgery (SSRF)

How convincing a server to make a request on an attacker's behalf turns a simple "fetch this URL" feature into a way to reach systems the attacker could never reach directly.

Typical ceiling: CriticalA10:2021 – Server-Side Request Forgery (SSRF)CWE-918
Ask Synthreat AI about Server-Side Request Forgery (SSRF) ✦Practice this on PortSwigger's Web Security Academy →

Definition

Server-side request forgery happens when an application fetches a remote resource based on a URL a user supplies, without validating or restricting where that fetch can actually go. The attacker never sends the malicious request themselves; they convince the server to send it on their behalf, using the server’s own network position to reach places the attacker could never reach directly.

The Trust Boundary That Breaks

Developers building a “fetch this URL” feature, a webhook validator, an image-from-URL uploader, a PDF generator that loads a page, trust that the feature will only ever be pointed at legitimate, external resources. The server making the request has no inherent way to distinguish a legitimate external URL from an internal-only address or a cloud provider’s metadata endpoint. Both are just strings that look like URLs. The server itself can reach both; the external attacker who supplied the URL cannot reach either directly, which is exactly why getting the server to make the request for them is valuable.

Where It Actually Shows Up

Why It Keeps Happening

A “fetch a URL” feature is genuinely useful and common, and validating that a supplied string is syntactically a URL feels, to a developer building it quickly, like the same thing as validating that it’s a safe destination. It isn’t. A hostname can resolve to an internal address; a redirect from an allowed domain can land somewhere entirely different; the same request-making code path is often reused across features without anyone revisiting its destination restrictions each time.

How to Find It

  1. Identify every feature that fetches a resource based on a user-supplied URL, including indirect ones like webhook validators and link previews, not just obvious “upload from URL” buttons.
  2. Test whether internal-only or link-local addresses are reachable through the feature, using a controlled test destination rather than a real internal system.
  3. Test whether the restriction, if one exists, is enforced after DNS resolution rather than on the string as typed, since a hostname can resolve to a different address than it appears to point to.
  4. In cloud environments, test specifically whether the feature can reach the instance metadata service, since that’s frequently the highest-value destination reachable this way.

Impact by Scenario

Scenario Realistic impact
Fetch feature restricted to a strict allowlist of external domains, validated after DNS resolution Attack surface effectively closed; there’s no internal destination to redirect the request to
Fetch feature with a denylist of “known bad” addresses only Bypassable through alternate IP encodings, redirects, or DNS tricks; provides limited real protection
Fetch feature reaching a cloud instance’s metadata endpoint Potential exposure of temporary credentials scoped to whatever that instance is permitted to do
Fetch feature reaching an internal admin interface with no external exposure otherwise A path to an interface that was never designed to be reachable from outside the network at all

Why a Business Should Care

SSRF is one of the more counterintuitive findings to explain to a client, because the vulnerable feature itself often looks completely benign: an image upload, a link preview, a webhook check. The useful framing is that any feature making a server-side request on a user’s behalf is, by definition, giving that user indirect network access from the server’s own position, and that access needs the same scrutiny as a direct network connection would get, not less scrutiny because it’s wrapped in a convenience feature.

A Worked Example

(Generalized from real assessment patterns. Company and identifiers below are invented; no real system, client, or data is referenced.)

Brindlewood Media’s application includes a profile picture feature that fetches a user-supplied image URL server-side and stores the result. During an assessment, supplying a cloud metadata service address in place of a real image URL causes the server to fetch and return metadata service content instead of an image, confirming the internal-only endpoint is reachable through the feature.

Testing stops at confirming that this internal-only endpoint responds through the flaw. No credentials or further data are extracted from the metadata response; proving reachability is sufficient to demonstrate the finding without pursuing anything beyond it.

sequenceDiagram
    participant Tester as Security Tester
    participant App as Brindlewood Media Web App
    participant Egress as Server Fetch Worker
    participant IMDS as AWS EC2 Metadata Service (169.254.169.254)

    Tester->>App: POST /api/avatar/fetch {"image_url": "http://169.254.169.254/latest/meta-data/"}
    App->>Egress: Delegate image fetch task
    Note over Egress: Worker does not validate private IP or link-local address space
    Egress->>IMDS: GET /latest/meta-data/ (Origin: Local EC2 Instance)
    IMDS-->>Egress: HTTP/1.1 200 OK (Directory listing: iam/, instance-id, hostname)
    Egress-->>App: Raw body returned to application
    App-->>Tester: 200 OK (Renders metadata service directory list in response)
    Note over Tester,IMDS: SSRF reachability to cloud metadata confirmed ethically - testing halts before querying IAM credentials

Severity Calibration

Severity depends heavily on what’s actually reachable through the flaw, not on the existence of the flaw alone. Reaching a cloud metadata endpoint capable of yielding live credentials typically justifies a Critical rating; reaching only a low-value internal status page with no further access potential rates meaningfully lower, even though the underlying coding pattern is identical in both cases.

Remediation

The real fix is a strict allowlist of permitted destination domains or IP ranges for any server-side fetch feature, validated after DNS resolution rather than on the string as typed, combined with network-level restrictions on what the fetching service can reach at all. The common bad fix is a denylist of “known bad” addresses, which is trivially bypassed with alternate IP encodings, open redirects, or DNS tricks that resolve differently at request time than they appeared to at validation time.

AI Technical Drill

Test Your Understanding

On-demand, Gemini-generated technical drill testing root causes, exploit chains, and verified defenses.

🤖

Generate On-Demand Technical Quiz

Synthreat AI analyzes this topic's attack surface and compiles custom multiple-choice questions with verified explanations.

Question Count: