Part II β The Shield Β· Lesson 3.1
Server-Side Request Forgery (SSRF)
In one lineYour server fetches a URL the attacker chose, from inside your trusted network.
Where you've seen itAny "Import from URL", "Add by link", or link-preview feature β the user supplies a URL and your backend goes and fetches it.
Diagram
THE PIVOT β the attacker borrows your server's network position
ββββββββββββ "preview this: ββββββββββββββββββββ
β Attacker β http://169.254.169.254/..." βΊβ Your server β
ββββββββββββ ββββββββββ¬ββββββββββ
β fetch()
the internet cannot reach these βββ β
βΌ βΌ
ββββββββββββββββββββββββββββββββββββββββ
β 169.254.169.254 cloud metadata β
β 10.0.0.0/8 internal services β
β 127.0.0.1:6379 redis, no auth β
β file:///etc/passwd β
ββββββββββββββββββββββββββββββββββββββββ
response comes back in the "preview" cardWHY ALLOWLISTS MUST RESOLVE, NOT PARSE
blocked by string check? still resolves to 127.0.0.1
ββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ
http://127.0.0.1 β obvious
http://0177.0.0.1 octal
http://2130706433 decimal
http://localtest.me public DNS β 127.0.0.1
http://evil.com DNS returns 10.0.0.5 β rebinding
Validate the RESOLVED IP, immediately before connecting.How it works
- A feature accepts a URL from the user and the server fetches it.
- The server sits inside the perimeter, so it can reach cloud metadata, internal APIs, and unauthenticated databases.
- The response β or even just the timing and error difference β leaks internal information back to the attacker.
- Defence: allowlist schemes (
http,httpsonly) and hosts, resolve DNS yourself, reject private and link-local ranges, and re-check after every redirect. - Defence in depth: run the fetcher in an egress-restricted network segment with no metadata access.
CHECKLIST
β scheme allowlist no file:, gopher:, ftp:, data:
β resolve then validate reject 10/8, 172.16/12, 192.168/16,
127/8, 169.254/16, ::1, fc00::/7
β disable auto-redirects or re-validate every hop
β timeout + size cap no infinite streams
β strip response headers return only what the feature needs
β separate egress subnet block metadata at the network layerTrade-offs
| Approach | Strength |
|---|---|
| Host allowlist | Strongest β use when the set of sources is known |
| IP-range denylist | Necessary but bypassable alone |
| Network egress rules | Survives application bugs |
| Dedicated fetch service | Blast radius contained to one box |
Interview angle
"Where does SSRF show up in a frontend-facing feature?"
- Anywhere the user supplies a URL your backend then fetches: link previews, imports, webhooks, avatar-by-URL, PDF/screenshot renderers.
- Headless-browser screenshot services are especially exposed β they follow redirects and run JS.
- The fix is resolve-then-validate plus network egress restrictions, not a regex on the string.
Recap
- SSRF turns your server into the attacker's proxy inside the perimeter.
- Validate the resolved IP right before connecting, and again after each redirect.
- Cloud metadata endpoints are the classic target β block them at the network too.