API Security Server Side Request Forgery

Many APIs fetch web addresses on behalf of users. A profile feature imports a photo from a link. A webhook feature calls a customer's URL. A preview feature loads a page title. Server Side Request Forgery, known as SSRF, appears when an attacker supplies an address and the API server makes the request from inside the trusted network.

Layman's Explanation

Imagine a company mailroom clerk who delivers any parcel a stranger names. A stranger writes "Pick up a package from the locked executive office." The clerk holds a staff badge, walks inside, and returns with the package. Outsiders cannot enter that office, but the clerk can. SSRF turns the API server into that clerk.

Why the Risk Is High

The API server sits behind firewalls. It reaches internal admin panels, databases, and cloud services that the internet cannot touch. A forged request borrows that trusted position. Cloud platforms expose a metadata service on a private address, and that service can hold temporary access credentials. Stolen credentials let an attacker act inside the cloud account.

Attack Flow Diagram

 Attacker          Public API Server          Internal Network
    |                     |                          |
    |  "Import image      |                          |
    |   from this URL"    |                          |
    |-------------------> |                          |
    |                     |  GET internal address    |
    |                     | ------------------------>|
    |                     |                          |
    |                     |<---- private data ------ |
    |<-- data returned -- |                          |

Features That Invite SSRF

  • Webhook registration and testing
  • Image, avatar, or document import by link
  • URL preview and link unfurling
  • PDF generators that load remote pages
  • Integration settings that accept a custom server address

Defense Strategy

Use an Allowlist

Permit only known, trusted domains whenever the feature allows it. An allowlist beats a blocklist, since attackers invent new ways to write a blocked address.

Validate After DNS Resolution

Resolve the hostname to an IP address first. Reject results that point to private ranges, loopback, link-local space, or the cloud metadata address. Check the resolved address again at connection time to stop DNS tricks that change the answer between checks.

Restrict Protocols and Ports

Allow only HTTPS, and only on standard ports. Refuse schemes such as file, gopher, and ftp.

Control Redirects

Turn off automatic redirects, or validate every redirect target with the same rules. A safe first address can bounce to a dangerous one.

Segment the Network

Place the component that fetches URLs in a separate network zone with limited reach. Apply egress rules that permit outbound traffic only to approved destinations.

Harden the Cloud Layer

Enable the stronger version of the metadata service that requires session tokens. Grant each server role only the permissions it needs, so stolen credentials carry little value.

Limit What the Response Reveals

Return a simple success or failure message. Never echo the full body that the remote address returned. Add short timeouts and size caps to stop slow or huge responses.

Defense Layers at a Glance

 User URL
    |
    v
 [1] Allowlist check ---------- fail --> reject
    |
    v
 [2] DNS resolve + IP check --- fail --> reject
    |
    v
 [3] Protocol and port check -- fail --> reject
    |
    v
 [4] Fetch with timeout, no redirects, size cap
    |
    v
 [5] Egress firewall allows only approved targets
    |
    v
 Safe, limited response

Testing Your Own API

List every endpoint that accepts a URL, hostname, or IP address. Submit addresses that point to your own test servers and watch the incoming requests. Confirm that internal ranges and the metadata address are rejected. Record each result in the test report and retest after every change to the fetching code.

Real-World Lessons

Large cloud breaches have started with a single URL-fetching feature. Developers built the feature for convenience, and nobody reviewed what addresses the server could reach. Treat every outbound request as a security decision. Ask three questions during design: who supplies the address, what can the server reach, and what does the response reveal?