SSRF Pentest Methodology: From Discovery to Cloud Metadata
Cybersecurity
A request-level walkthrough of how authorized pentesters surface SSRF in URL fetchers, webhooks, and image proxies, plus the egress controls and IMDSv2 settings that shut it down for good.
By Arjun Raghavan, Security & Systems Lead, BIPI · December 22, 2024 · 8 min read
Server-Side Request Forgery remains one of the highest-impact web bugs because a single vulnerable parameter can pivot a public web app into the cloud control plane. This playbook walks through the request patterns we use during authorized engagements and the controls that consistently kill the bug class.
Where SSRF hides
Start with any feature that takes a URL or hostname from the user. Webhook configuration, profile-image-by-URL, PDF/HTML render services, link previews, OAuth callback fetchers, RSS importers, and SSO metadata fetchers all qualify. Use Burp's HTTP history filter on the word http or https in request bodies, and run ffuf with a wordlist of ten common parameter names like url, image, dest, callback, target, link, redirect, proxy, fetch, and host.
How to test for it
Replace the user-supplied URL with a unique Burp Collaborator or interactsh subdomain and watch for an out-of-band hit. Confirm the request originates from the application's egress IP, not the victim's browser, by comparing the Collaborator source IP to the public DNS A record of the target.
- Probe with http://collab.oast.fun and look for HTTP plus DNS records.
- Test 127.0.0.1, 0.0.0.0, [::1], and decimal IPs like 2130706433 to bypass naive blocklists.
- Try DNS rebinding with services like 1u.ms or rbndr.us when the app resolves the hostname twice.
- Use redirect chains: host a 302 to http://169.254.169.254 on attacker-controlled infrastructure.
- Encode the host as http://[email protected]/ to confuse URL parsers.
On AWS targets without IMDSv2, fetch http://169.254.169.254/latest/meta-data/iam/security-credentials/ and grab role credentials. On GCP, the metadata endpoint requires the Metadata-Flavor: Google header, so test header-injection variants too.
Detection signals
On the network side, alert on outbound HTTP from application subnets to RFC1918 ranges, link-local 169.254.0.0/16, and the cloud metadata IP. VPC flow logs plus a Sigma rule on dst_addr matching those ranges from web tier ENIs catches most exploitation. At the application layer, log every URL passed to outbound fetchers with the resolved IP after DNS lookup, then alert when the resolved IP differs from the originally-resolved IP, which is the DNS rebinding tell.
Remediation
- Enforce IMDSv2 on every EC2 instance and set hop limit to 1 so containers cannot reach metadata.
- Route outbound traffic from app servers through a forward proxy that allowlists known third-party hostnames.
- Reject any URL that resolves to RFC1918, link-local, loopback, or cloud metadata IPs after DNS resolution. Resolve once, validate, then connect to that exact IP.
- Use library-level SSRF protection: ssrf-req-filter for Node, the requests-ip-filter pattern in Python, or Go's net.Dialer with a Control function that rejects private IPs.
- Move sensitive third-party calls behind PrivateLink endpoints so even a compromised egress proxy cannot reach the public internet.
Validation after fix
Re-run the original Collaborator payload, then re-test with each bypass technique. Confirm IMDSv2 with aws ec2 describe-instances --query 'Reservations[].Instances[].MetadataOptions'. Run a nuclei template with -t http/vulnerabilities/generic/ssrf-via-oob.yaml against staging and check that every fetcher endpoint returns a deterministic block, not a timeout, since timeouts often mean the connection was made but discarded.
BIPI runs SSRF-focused engagements that map every outbound fetcher in your codebase, exercise twenty-plus bypass variants, and deliver remediation patches your team can ship the same sprint.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.