Server-Side Request Forgery
Comprehensive guide to SSRF vulnerabilities, how attackers exploit server-side requests to access internal systems, cloud metadata, and bypass network controls.
What is Server-Side Request Forgery?
Server-Side Request Forgery (SSRF) occurs when an attacker can induce the server-side application to make HTTP requests to an arbitrary domain, IP address, or port of the attacker's choosing. This vulnerability arises when an application fetches remote resources based on user-supplied URLs without proper validation and restriction. SSRF was elevated to its own category in the OWASP Top 10 2021, reflecting its increasing prevalence and the severity of its impact, particularly in cloud-hosted environments where it can lead to complete infrastructure compromise.
SSRF is especially dangerous because the requests originate from the server itself, which typically has elevated network access compared to external attackers. The server often resides within a trusted network zone with access to internal services, databases, cloud metadata endpoints, and administrative interfaces that are not accessible from the public internet. By exploiting SSRF, an attacker effectively uses the vulnerable application as a proxy to reach these otherwise protected resources, bypassing firewalls, VPNs, and network segmentation controls.
Common SSRF scenarios include:
- URL preview or link fetching features (social media cards, URL shortener previews, webhook delivery) where the application fetches content from a user-supplied URL
- File import from URL functionality (importing images, CSV files, or documents from external URLs)
- PDF generation services that render HTML from user-supplied URLs or HTML content containing external resource references
- Webhook configurations where the application sends HTTP requests to user-configured endpoints
- API gateways and proxy functions that forward requests based on user input
- Cloud metadata endpoint access (e.g., AWS
http://169.254.169.254/latest/meta-data/) that can expose IAM credentials, instance configuration, and secrets - Accessing internal services like Redis, Elasticsearch, Memcached, or administrative dashboards that bind to localhost or internal interfaces
How It Works
The basic SSRF attack involves supplying an internal URL where the application expects an external resource. For example, if an application has a feature that fetches and displays a preview of a URL:
POST /api/fetch-preview HTTP/1.1
Content-Type: application/json
{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-role"}
If the application fetches this URL without validation, it will retrieve the AWS EC2 instance's IAM role credentials, which the attacker can use to authenticate to AWS services with the instance's permissions. This can lead to reading S3 buckets, accessing RDS databases, invoking Lambda functions, or even full AWS account compromise depending on the IAM role's permissions.
Attackers use various techniques to bypass SSRF protections. URL parsing inconsistencies between the validation logic and the HTTP library can be exploited using URL formats like: http://127.0.0.1:80@evil.com/, http://evil.com#@169.254.169.254/, or http://0x7f000001/ (hexadecimal representation of 127.0.0.1). DNS rebinding is an advanced technique where the attacker controls a domain that initially resolves to an allowed IP address (passing validation) but then resolves to an internal IP on subsequent requests. Alternative IP representations that bypass naive blocklists include: http://0177.0.0.1/ (octal), http://2130706433/ (decimal), http://[::1]/ (IPv6 loopback), and http://127.1/ (abbreviated).
Blind SSRF occurs when the application makes the server-side request but doesn't return the response content to the attacker. Exploitation is still possible through: out-of-band techniques (making the server contact an attacker-controlled domain to confirm reachability), time-based inference (measuring response times to determine if internal ports are open), and chaining with other vulnerabilities. For example, blind SSRF can be used to interact with internal services that have unauthenticated command interfaces, such as sending a SLAVEOF command to an internal Redis instance or querying an internal Elasticsearch cluster. In cloud environments, even blind SSRF can be devastating if the attacker can make the application POST to internal APIs that perform actions (like modifying security groups or creating IAM users).
Impact
- Cloud infrastructure compromise through metadata endpoint access: extraction of IAM credentials (AWS), managed identity tokens (Azure), service account tokens (GCP) that can provide full cloud account access
- Internal network scanning and enumeration, allowing attackers to map internal infrastructure, discover services, and identify further attack targets behind the firewall
- Access to internal services not exposed to the internet: databases, caches (Redis, Memcached), message queues, monitoring dashboards, and administrative interfaces
- Data exfiltration from internal systems by reading files via file:// protocol (where supported), accessing internal APIs, or querying databases through internal network access
- Remote Code Execution when SSRF is chained with vulnerable internal services (e.g., unauthenticated Redis with SLAVEOF, internal Jenkins with script console, Elasticsearch with scripting enabled)
- Bypassing network security controls: firewalls, network segmentation, VPN requirements, and IP-based access controls by pivoting through the trusted server
- Denial of service against internal systems by directing the server to make a large number of requests to internal endpoints or by exploiting amplification in internal services
- Cryptocurrency mining or other resource abuse when SSRF provides access to cloud APIs that can provision additional compute resources
Remediation Steps
- Implement strict URL validation on the server side. Parse the URL and validate the scheme (allow only
https://andhttp://, blockfile://,gopher://,dict://,ftp://), the host (resolve the hostname and verify the resolved IP is not in a private range), and optionally the port. Perform validation AFTER DNS resolution to prevent DNS rebinding attacks and TOCTOU issues. - Block requests to private and reserved IP ranges:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,169.254.0.0/16(link-local/metadata),::1/128,fc00::/7, andfe80::/10. Be thorough with blocking: check all IP representations (decimal, hex, octal, IPv6-mapped IPv4) and resolve all DNS lookups before comparing against blocklists. - Implement network-level controls as defense-in-depth. Use firewall rules to prevent the application server from making requests to the cloud metadata service (block
169.254.169.254at the network level). On AWS, use IMDSv2 which requires a token obtained via a PUT request, making SSRF exploitation significantly harder. On GCP and Azure, configure similar metadata endpoint protections. - Use an allowlist approach where possible. If the application only needs to fetch resources from known domains, maintain an allowlist of permitted domains and reject all others. This is far more secure than a blocklist approach which inevitably has bypasses.
- Disable unnecessary URL schemes and follow redirects carefully. Even if the initial URL passes validation, a redirect could point to an internal resource. Follow redirects with the same validation applied at each hop, or disable redirect following entirely. Limit the maximum number of redirects.
- Implement dedicated network segments for applications that need to fetch external URLs. Place these applications in a DMZ with no access to internal networks, cloud metadata, or sensitive services. Use an egress proxy that enforces URL policies and logs all outbound requests.
- For webhook and callback features, validate the destination URL at configuration time AND at delivery time (the resolved IP may change). Implement signing mechanisms so webhook recipients can verify the request originated from your application. Rate limit outbound webhook deliveries.
- Monitor and alert on unusual outbound request patterns from application servers: requests to internal IP ranges, cloud metadata endpoints, unusual ports, or high-volume requests to a single destination. Log all outbound requests made by the application with full URL, response status, and response size for forensic analysis.
Testing Guidance
Testing for SSRF requires identifying all application features that make server-side HTTP requests based on user input. Map features like URL previews, file import from URL, webhook configurations, image/document fetching, and any parameter that accepts a URL. Test each input with a Burp Collaborator or interactsh callback URL first to confirm that the server makes outbound requests based on your input: http://your-id.burpcollaborator.net. If you receive a DNS lookup or HTTP request, SSRF is confirmed and you can proceed to test for internal access.
Systematically test access to internal resources. Start with the cloud metadata endpoint: http://169.254.169.254/latest/meta-data/ (AWS), http://metadata.google.internal/computeMetadata/v1/ (GCP with header Metadata-Flavor: Google), or http://169.254.169.254/metadata/instance (Azure). Test access to common internal services: http://127.0.0.1:6379/ (Redis), http://127.0.0.1:9200/ (Elasticsearch), http://127.0.0.1:8080/ (internal web services), and http://127.0.0.1:3000/ (Grafana, Gitea, etc.). If basic internal URLs are blocked, test bypass techniques: alternative IP representations (decimal http://2130706433, octal http://0177.0.0.1, hex http://0x7f.0x0.0x0.0x1), IPv6 (http://[::1], http://[0:0:0:0:0:ffff:127.0.0.1]), URL encoding, and double encoding.
Test for DNS rebinding by setting up a domain that alternates between resolving to an allowed external IP and an internal IP (tools like rbndr.us provide this capability). Test redirect-based bypasses by hosting a redirect on an external server: http://attacker.com/redirect -> http://169.254.169.254/. If the application follows redirects without re-validating, this bypasses domain-level allowlists. For blind SSRF (where you can't see the response), use time-based techniques: compare response times for requests to open vs. closed internal ports. Use tools like SSRFmap for automated exploitation across multiple protocols and targets. Test the file://, gopher://, and dict:// protocols which can be used to interact with various internal services beyond HTTP.
References
Related Vulnerabilities
Related Checklists
Frequently Asked Questions
What is Server-Side Request Forgery?
Server-Side Request Forgery (SSRF) occurs when an attacker can induce the server-side application to make HTTP requests to an arbitrary domain, IP address, or port of the attacker's choosing. This vulnerability arises when an application fetches remote resources based on user-supplied URLs without proper validation and restriction.
How does Server-Side Request Forgery work?
The basic SSRF attack involves supplying an internal URL where the application expects an external resource. For example, if an application has a feature that fetches and displays a preview of a URL: POST /api/fetch-preview HTTP/1.1 Content-Type: application/json {"url": "http://169.254.169.
How do you test for Server-Side Request Forgery?
Testing for SSRF requires identifying all application features that make server-side HTTP requests based on user input. Map features like URL previews, file import from URL, webhook configurations, image/document fetching, and any parameter that accepts a URL.
How do you remediate Server-Side Request Forgery?
Implement strict URL validation on the server side. Parse the URL and validate the scheme (allow only https:// and http://, block file://, gopher://, dict://, ftp://), the host (resolve the hostname and verify the resolved IP is not in a private range), and optionally the port. Perform validation AFTER DNS resolution to prevent DNS rebinding attacks and TOCTOU issues.