Application Security
Intermediate 17 min read Application Security

Server-Side Request Forgery (SSRF)

When your server fetches on the attacker's behalf: how SSRF tunnels into internal metadata, clouds, and admin services, and how to make fetching boring again.

SSRFrequest forgerycloud metadata169.254.169.254allow-listURL parsing
Introduction

What is this?

SSRF is a class of bug where the application fetches a URL supplied by the user, letting the attacker make the server reach internal resources that were never meant to be public.

Motivation

Why do you need it?

  • The classic tunnel: an 'import from URL' or 'image proxy' feature becomes a reading tool for the internal network.
  • On cloud, the metadata endpoint (169.254.169.254) hands over IAM credentials — that single string is the highest-value SSRF payload in existence.
  • It is invisible to black-box scanners because the effect happens server-side, on paths the scanner never guessed.
Think about it

Mental model

Imagine

A 'fetch this link' helper

Think of

A courier who will fetch ANY address you whisper

The courier has a key to the back office; the trick is making the courier go there.

Mechanics

How it works

  • Some endpoints accept a URL (webhooks, OCR, feed import) and the server makes outbound HTTP to it.
  • The fetch runs with the server's network credentials: localhost, VPC-internal load balancers, and the cloud metadata service are all 'nearby'.
  • Attackers redirect, use DNS rebinding, or encode URLs (http://127.1, decimal IP, @ in userinfo) to defeat naive filters.
  • Controls: strict allow-list of destinations, deny-listing by policy, IP-level blocking of metadata and link-local ranges, and SSRF-aware URL parsers.

SSRF reaching internal services

Request
Server fetch
Internal
Read
Exfiltrate
Real world

In production

  • A document previewer adds an SSRF allow-list: only the org's own storage buckets and safe hosts can be fetched.
  • A cloud team blocks egress to 169.254.169.254 at the runtime firewall so even successful SSRF gets a blank response.
  • An OCR service runs in a dedicated segment without credentials, so a forged fetch reaches nothing but a dead end.
Guidelines

Best practices

  • Never fetch arbitrary user URLs; require an allow-list of hosts/schemes, or a media-upload endpoint instead.
  • Block link-local (169.254.0.0/16, fe80::/10), loopback, and metadata ranges before any URL handling.
  • Resolve DNS then re-validate the resolved IP, and pin to a fixed-time ToC/ToU-safe design for import features.
  • Log the fetch target and duration; unexpected outbound try-fetches are early SSRF breadcrumbs.
Watch out

Common mistakes

  • Filtering only at the string level with 'block 169.254.169.254' — decimal/hex URLs and DNS rebinding sail through.
  • Checking the host before redirect, but the fetch follows redirects into the metadata network.
  • Giving the fetcher service the same credentials the application uses — the error surface becomes exfiltration surface.
  • Forgetting that webhooks/QR/import parsers count as fetch endpoints, and each needs the same guard.
When things break

Debugging tips

  • When an import feature silently fails on a host, compare the resolved IP against the allow-list — redirects are the usual cause.
  • Watch the server's own outbound connections (ss -tp) during a fetch; unexpected destinations reveal the SSRF path.
  • Use a public 'request bin' only on your own service, or log to your own listener, to see what your app fetches.
Security

Security considerations

  • Point your SSRF tests at your own services; probing a neighbor's metadata endpoint fires real cross-tenant alarms.
  • Treat the practice of 'just fetching anything' as a design anti-pattern to remove, not a config to tune.
  • Restriction is about data too: an SSRF that reads your own tokens is still a data breach — log and contain.
Interviews

Interview checkpoint

Practice

Hands-on lab

SSRF Against Your Own Micro-Service
45 min · intermediate
In progress
Objectives
  • Build a tiny 'fetch URL' service in your lab and reach localhost through it.
  • Observe the metadata-equivalent link-local access from inside the service.
  • Implement and validate an allow-list + IP-deny control.

SSRF Against Your Own Micro-Service

45 min · intermediate

0/4 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Which address is the primary SSRF target inside major clouds?

2

An SSRF control that blocks '127.0.0.1' strings can still be bypassed by...

Go deeper

Official documentation