OWASP Top 10:2021 — A10: Server-Side Request Forgery (SSRF)
We’ve reached the end of the OWASP Top 10 in this OWASP Top 10:2021 series — and we’re finishing with a bang. SSRF is one of the most dangerous vulnerabilities to emerge in modern architectures — especially in cloud-native apps and internal microservice environments.
Let’s unpack it.
Full series:
- A01: Broken Access Control
- A02: Cryptographic Failures
- A03: Injection Attacks
- A04: Insecure Design
- A05: Security Misconfiguration
- A06: Vulnerable and Outdated Components
- A07: Identification and Authentication Failures
- A08: Software and Data Integrity Failures
- A09: Security Logging and Monitoring Failures
- A10: Server-Side Request Forgery (SSRF) (you are here)
What Is SSRF?
Server-Side Request Forgery (SSRF) occurs when an attacker can make your server send HTTP (or other protocol) requests to internal or unintended targets — often bypassing firewalls and access controls.
In short: The attacker can’t reach a sensitive service — but your server can, and the attacker tricks it into doing so.
Why Is This a Big Deal?
SSRF is dangerous because it allows attackers to:
- Scan internal networks (e.g. http://127.0.0.1, http://10.0.0.0/8)
- Access metadata services (e.g. AWS http://169.254.169.254) to extract credentials
- Trigger requests to internal APIs (e.g. internal admin endpoints or CI/CD services)
- Bypass IP-based firewalls or allowlists
- In some cases, escalate to remote code execution if the internal service is vulnerable
What Does SSRF Look Like in Practice?
Let’s say your app allows users to fetch a URL for a preview, like:
GET /preview?url=https://example.com/image.jpg
The backend might fetch this URL, process the image, and return a preview.
But what if an attacker sends:
GET /preview?url=http://localhost:8080/admin
Or:
GET /preview?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
If your server doesn’t validate outbound requests, it could be used to:
- Reach internal-only services
- Extract AWS credentials
- Exploit internal APIs
How Attackers Exploit SSRF
SSRF thrives in cloud environments, microservices, and apps that make dynamic HTTP requests. It’s especially dangerous when:
- You host in AWS, GCP, or Azure (they all expose metadata services)
- You expose internal services (e.g. Prometheus dashboards, Jenkins) without auth
- Users can control request URLs for previews, notifications, or integrations
How Engineers Can Defend Against SSRF
- Deny Internal IP Ranges
Block requests to:
- 127.0.0.0/8, 10.0.0.0/8, 169.254.0.0/16, 192.168.0.0/16, etc.
- AWS metadata IPs (e.g. 169.254.169.254)
- Unix sockets (e.g. file:///, gopher://, ftp:// if applicable)
Use an allowlist of acceptable domains instead.
- Use DNS Pinning
Resolve the domain name once and pin its IP address — prevent DNS rebinding attacks where a domain resolves to an internal IP later.
- Avoid Direct User-Controlled URLs
Don’t let users directly control URLs sent by the server. If you must:
- Sanitise inputs
- Fetch through a secure proxy
- Strip redirect chains or responses
- Isolate Server Roles
Prevent web servers from having outbound access to sensitive internal systems. Use firewall rules to enforce this at the infrastructure level.
- Log and Monitor All Outbound Requests
Alert on requests to known internal IPs or unusual metadata services.
Real-World Case: Capital One (2019)
An SSRF vulnerability in a WAF (Web Application Firewall) exposed by a cloud misconfiguration let an attacker query AWS metadata.
They extracted temporary credentials and used them to access over 100 million customer records.
It wasn’t a code bug — it was a server-to-server trust issue.
Final Thoughts
SSRF is a classic example of a vulnerability born from modern architecture:
- Internal services with no auth
- Cloud metadata that trusts local servers
- Web apps acting as proxies for user input
You can’t just secure your frontend — you have to think about where your server can go, and who’s telling it to go there.
Leave a comment