Server-Side Request Forgery is an exploitation technique that lets an attacker make a server issue HTTP requests to arbitrary destinations. What does that mean in practice? Essentially, it happens when a web app fetches a remote resource without verifying and validating the URL supplied by the user.
SSRF has been the entry point for some of the most serious breaches of recent years, including the Capital One breach that exposed over 100 million records.

How it works

When a web application accepts a URL from the user and fetches it server-side, the conditions for SSRF are created. Common examples:

  • Importing images from a URL
  • Configurable webhooks and callbacks
  • RSS/XML feed parsers
  • PDF generators that load external resources
  • Proxies and URL shorteners

The server, trusting the input, makes the request. If the attacker supplies a URL pointing to internal resources, the server becomes an unwitting proxy into the protected infrastructure.

Legitimate request:
POST /api/fetch-image
{"url": "https://example.com/logo.png"}

Malicious request:
POST /api/fetch-image
{"url": "http://169.254.169.254/latest/meta-data/"}

Why 169.254.169.254 is scary

That IP address is the metadata service of cloud providers (AWS, GCP, Azure). From an EC2 instance it's reachable only internally and returns sensitive information: temporary IAM credentials, API keys, session tokens.

An SSRF that reaches the metadata service can extract highly privileged credentials. From there the attacker can access S3 buckets, RDS databases, secrets managers. The network perimeter collapses.

AWS introduced IMDSv2, which requires a token to access metadata, but many instances still use v1 or have v2 configured as optional.

Bypassing filters

Developers' first instinct is to filter URLs. Block localhost, 127.0.0.1, private addresses. Does it work? Rarely.

DNS Rebinding: the attacker controls a domain that initially resolves to a public IP (passing the filter) and then changes its resolution to an internal IP. The server has already validated the URL, and the request goes out to the internal address.

Encoding and alternative representations:

  • 127.0.0.1 becomes 2130706433 (decimal)
  • 127.0.0.1 becomes 0x7f000001 (hexadecimal)
  • localhost becomes localtest.me (a public domain that resolves to 127.0.0.1)
  • IPv6: [::] is equivalent to 0.0.0.0

Redirect chain: the URL points to a server controlled by the attacker that responds with a 302 redirect to the internal destination. The filter only validates the initial URL.

URL parser inconsistencies: differences between how the filter parses the URL and how the HTTP library interprets it. Characters like @, #, and multiple layers of encoding can confuse validation.

http://attacker.com#@internal-server/admin
http://internal-server:[email protected]/
http://attacker.com/?url=http://internal-server/

From SSRF to RCE

SSRF becomes critical when it reaches internal services without authentication:

Redis (port 6379): many installations don't require a password. With the RESP protocol, it's possible to inject commands through a malformed HTTP request. Writing a key with a cron job or an SSH key leads to RCE.

Memcached (port 11211): same principle. Injecting serialized data that the application will later deserialize.

Docker API (port 2375): if exposed without TLS, it allows creating privileged containers, mounting the host filesystem, and running commands as root.

Consul, etcd, Kubernetes API: orchestration services often reachable without authentication from the internal network. Reading secrets, configurations, and the possibility of malicious deployments.

Elasticsearch (port 9200): reading and writing indexes, potential access to logs and sensitive data.

Testing

Identifying SSRF requires a server to receive callbacks. Burp Collaborator does this job: it generates unique URLs and notifies you when they receive requests.

Free alternatives:

  • interactsh (ProjectDiscovery)
  • webhook.site
  • requestbin.com

Parameters worth testing:

  • Any field that accepts a URL
  • Headers like X-Forwarded-For, Referer (in some cases processed server-side)
  • Hidden parameters discovered through fuzzing

Initial payloads:

http://collaborator-url/
http://169.254.169.254/latest/meta-data/
http://[::]:22/
http://127.0.0.1:6379/

Mitigation

Whitelist, not blacklist: at the firewall level you need to enforce deny-all policies or very strict ACLs to block all non-essential traffic.

Post-DNS-resolution validation: check the destination IP after DNS resolution, not just the input URL. Block private ranges (10.x, 172.16-31.x, 192.168.x, 169.254.x, 127.x).

Disable redirects: if not needed, prevent the HTTP library from automatically following redirects.

Network segmentation: isolate application servers from critical internal services. The metadata service should only be reachable from the instances that actually need it.

IMDSv2 on AWS: enforce token-based access to metadata. Don't leave v1 as a fallback.

Timeouts and rate limiting: limit the number of outbound requests and the wait time. This slows down exploitation and makes scanning attempts more visible.

References

  • OWASP SSRF Prevention Cheat Sheet
  • PortSwigger Web Security Academy - SSRF
  • HackerOne Reports (filter by SSRF)
  • Capital One Breach Analysis (Krebs on Security)