FlawOpen

Vulnerabilities/Server-Side Request Forgery (SSRF)

Server-Side Request Forgery (SSRF)

High CWE-918
Language: English Português (Brasil) Español Français Deutsch Русский 简体中文 日本語 हिन्दी 한국어 Bahasa Indonesia

Server-side request forgery happens when an application fetches a URL that a user controls, for a link preview, webhook, image import or PDF renderer, and the server's network position lets that request reach addresses the user never could: 127.0.0.1, private subnets, admin ports and the cloud metadata service at 169.254.169.254. Checks on the URL string, or on a DNS answer taken before the request, fail against IP encodings, redirects and DNS rebinding. The fix is the same everywhere: check the actual IP address at the moment the socket connects, allow only http and https, do not follow redirects or use an environment proxy, set timeouts and a body cap, and enforce IMDSv2. Pick your language below for the exact hook, vulnerable and fixed code, and the linters that catch it.

Plain English Explainer (ELI5)

A hotel lets guests ask the concierge to collect a parcel from any address in town. You write down the address of the hotel's own staff-only office upstairs, where the master keys hang. The concierge wears a staff badge, walks straight in and brings you the key box, because the form only asked for an address, never whether that address is outside the hotel. A server that fetches URLs for users works the same way: from inside the network it can reach 127.0.0.1, internal APIs and the cloud metadata service at 169.254.169.254. The fix is to check where the concierge actually arrives, not just the address on the form, and to refuse notes on the door that say 'go upstairs instead'.

Core Concepts & Subsystem Terms

SSRF (CWE-918)
A server-side component sends a network request to a destination that request data controls, so an outside user can make the server reach hosts and ports that only the server's network can reach.
Cloud metadata service (IMDS)
Cloud VMs expose instance credentials at http://169.254.169.254/. IMDSv1 answers any GET; IMDSv2 requires a PUT for a session token and a hop limit, which blocks most SSRF. The 2019 Capital One breach read IAM keys through this service.
Allowlists that check the wrong thing
Comparing the hostname string, a prefix or a regex misses 127.1, 0x7f000001, [::ffff:127.0.0.1], user@host tricks and redirects to internal URLs, and a check on the first DNS answer says nothing about the address the client later connects to.
DNS rebinding
An attacker's DNS server answers the validation lookup with a public address and the HTTP client's own lookup a moment later with 127.0.0.1. Any check that resolves separately from the connection loses this race.
Connect-time address check
Hook the HTTP client where it opens the socket (Go Dialer.Control, OkHttp Dns, .NET ConnectCallback, Node lookup, libcurl CURLOPT_OPENSOCKETFUNCTION) or pin the connection to an IP you already checked, so the address you validate is the address you use.

Step-by-Step Attack Flow

Step 1

A feature fetches a user URL

A link preview, webhook tester, avatar import or HTML-to-PDF renderer passes request data to an HTTP client.

Step 2

The URL points inward

It names 127.0.0.1, a private host, 169.254.169.254, an encoded IP, a hostname that rebinds, or a public page that redirects inward. The benign test value http://127.0.0.1:8080/health illustrates the case.

Step 3

The internal service trusts the server

Admin panels, databases with HTTP interfaces, cache servers and the metadata service answer because the request comes from inside the network.

Step 4

The attacker reads secrets or pivots

Response bodies, status codes or timing leak credentials, configuration and open ports, and stolen cloud keys work from anywhere.

SSRF guides by language

Python JavaScript Go Java PHP C# Ruby C/C++ Rust Kotlin Swift

Engineering & System Hardening Checklist

Related reading

What is SSRF and why does cloud metadata matter? Is fetch() vulnerable to SSRF by default? SSRF through AI pull-request bots Capital One SSRF and IMDS breach (2019)