FSD Frontend System Design

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.

  • Time14 min
  • DiagramServer pivoting from the public internet into private IPs
  • Chapter3 Β· Security

Diagram

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" card
diagram
WHY 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

  1. A feature accepts a URL from the user and the server fetches it.
  2. The server sits inside the perimeter, so it can reach cloud metadata, internal APIs, and unauthenticated databases.
  3. The response β€” or even just the timing and error difference β€” leaks internal information back to the attacker.
  4. Defence: allowlist schemes (http, https only) and hosts, resolve DNS yourself, reject private and link-local ranges, and re-check after every redirect.
  5. Defence in depth: run the fetcher in an egress-restricted network segment with no metadata access.
diagram
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 layer

Trade-offs

ApproachStrength
Host allowlistStrongest β€” use when the set of sources is known
IP-range denylistNecessary but bypassable alone
Network egress rulesSurvives application bugs
Dedicated fetch serviceBlast 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.