DEV Community

OnaEiuspkz
OnaEiuspkz

Posted on

Server-side request forgery: the redirect that walks past your allowlist

Server-side request forgery: the redirect that walks past your allowlist

What makes SSRF resilient

A server that fetches a URL supplied by a user is making the request from a position of trust. The classic outcome is access to an internal service, and the modern high-value target is the cloud instance metadata endpoint, which on many platforms answers on the link-local address 169.254.169.254. The metadata service hands out temporary credentials to anything that asks from the instance, which turns one HTTP request into control of the workload's cloud identity.

The reason simple filtering fails is that the attacker chooses the redirect chain as well as the first URL. A fetched resource can answer with a redirect to an address the allowlist would have rejected, and a client that follows redirects automatically has already made the request by the time any check runs.

Why allowlists still win, and where they leak

OWASP's guidance puts allowlists first, and the reasoning holds: the set of destinations a feature legitimately needs is almost always small and enumerable. A denylist has to anticipate every representation of an internal address, including decimal, octal and hexadecimal forms, IPv6 mapped forms, and DNS names that resolve to internal addresses after the check.

The leak is the gap between the check and the use. If the address is validated once and the request is then made by a client that resolves the name a second time, a DNS record that changes between the two lookups defeats the validation. If the client follows redirects, the validation applies to the first hop only. Both are time-of-check to time-of-use problems, and both are fixed by validating at the point of use.

A design that holds

Resolve the name, validate the resulting address, and connect to that address directly rather than to the name. Disable automatic redirect following and handle redirects explicitly, revalidating each hop against the same rules. Restrict the scheme to HTTPS and set a short timeout. Where the fetch can reach a metadata endpoint, use the platform control: on AWS, IMDSv2 requires a session token that a simple SSRF cannot obtain, and lowering the hop limit restricts which processes on the instance can reach the service.

Where the feature only needs to fetch from a known set of hosts, replace URL input with a host identifier and build the URL from a template. That removes attacker control over the destination entirely and is the only design with no bypass class of its own.

Testing

Send a request that points at the metadata address directly and confirm it is refused. Then send a request that points at a controlled external host that responds with a redirect to the metadata address, and confirm the redirect is either refused or revalidated. The second test is the one that finds the gap, and it is cheap to run whenever the fetch code changes.

References

  1. Server-Side Request Forgery Prevention Cheat Sheet, OWASP. https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
  2. Configure the instance metadata service, Amazon EC2 User Guide. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
  3. RFC 9110, HTTP Semantics. https://www.rfc-editor.org/rfc/rfc9110.html

Top comments (0)