Agent Wranglers

APS-41Required

Fetch only allowed addresses

When the server fetches an address a user gave, allow only the hosts it needs. Never reach internal or cloud metadata addresses.

How to do it

Keep an allow-list of hosts and allow only https, or http where needed. Parse the address with one standard parser, then resolve the name. Refuse private, loopback, link-local, unspecified and multicast addresses in IPv4 and IPv6. That includes 0.0.0.0, ::1, fc00::/7, fe80::/10 and IPv4 inside IPv6, such as ::ffff:127.0.0.1. Compare the resolved address, never the text, since 2130706433 and 0x7f.1 both mean 127.0.0.1. Connect to the address you checked, so a second DNS answer cannot swap it, which is called DNS rebinding. Turn redirects off, or check each hop again with the same code. Cap the answer size and the time, such as 1 MB and 5 seconds. Push endpoints sent by browsers need the same care, as Accept push endpoints only from known push services says. Use a library or an egress proxy rather than your own IP parser. Block the cloud metadata addresses, 169.254.169.254 and fd00:ec2::254, at the network too. On AWS, require IMDSv2 with a hop limit of 1, so a container cannot reach it.

Examples

Plain text example

http://127.0.0.1:8080/
http://169.254.169.254/latest/meta-data/
http://[::1]/
http://0x7f000001/
http://0.0.0.0:8080/
http://metadata.google.internal/computeMetadata/v1/
http://[fd00:ec2::254]/latest/meta-data/
https://redirect.example.net/to?url=http://10.0.0.5/

How to check

On the test copy, the agent gives the fetch feature http://127.0.0.1, http://2130706433, http://[::ffff:127.0.0.1] and http://169.254.169.254. It adds a name that resolves to 10.0.0.5 and an address that redirects inside. Then it tries a name whose DNS answer changes from public to internal between two lookups. Every fetch is refused, and the internal test server logs no request.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/requests-files-and-caches/block-server-side-request-forgery">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.