Advanced Server-Side Request Forgery (SSRF) Vulnerability and Protection
1. Vulnerability Description
SSRF (Server-Side Request Forgery) is a security vulnerability where an attacker crafts a request that is then initiated by the server. Typically, SSRF attacks target internal systems that are inaccessible from the external network. Advanced SSRF vulnerabilities encompass not only basic internal network reconnaissance but also involve bypass techniques, cloud service metadata exploitation, port scanning, and combined exploitation with other vulnerabilities.
2. In-Depth Vulnerability Principle
- Attack Flow: Attacker submits a carefully crafted URL to a web application → Server-side code fetches the content of that URL without validation → Server initiates a request to the target address using its own identity → Response data is returned to the attacker.
- Key Point: The vulnerability exploits the server's network access privileges, potentially allowing attackers to access restricted resources such as internal systems and cloud metadata.
- Common Trigger Scenarios: Online translation, data fetching, image downloading, webhook callbacks, and other functionalities that require the server to initiate network requests.
3. Advanced Attack Techniques
-
URL Parsing Bypass:
- Using the
@symbol:http://evil.com@internal.ip/ - DNS rebinding: Utilizing DNS services to resolve the same domain name to different IPs within a short period
- Short URLs and redirect services to hide the real target address
- IPv6 and special encodings (octal, hexadecimal) for IP addresses
- Using the
-
Cloud Metadata Service Exploitation:
- AWS metadata:
http://169.254.169.254/latest/meta-data/ - Azure metadata:
http://169.254.169.254/metadata/instance - GCP metadata:
http://metadata.google.internal/computeMetadata/v1/ - Obtaining sensitive configuration information, temporary credentials, etc., from cloud servers via SSRF
- AWS metadata:
-
Protocol Exploitation:
- File protocol to read local files:
file:///etc/passwd - Dict protocol to probe port services:
dict://internal.ip:port/ - Gopher protocol to enable communication over various protocols (Redis, MySQL, etc.)
- File protocol to read local files:
4. Vulnerability Detection Methods
-
Black-Box Testing:
- Submitting URLs with different protocols and observing response differences
- Using tools like Burp Collaborator to detect out-of-band data interactions
- Attempting to access known internal network addresses and cloud metadata endpoints
-
Code Audit:
- Identifying network request functions (e.g., curl, file_get_contents)
- Checking if URL parameters undergo strict validation
- Analyzing whether the request target is user-controllable and unrestricted
5. Advanced Protection Strategies
-
Enhanced Input Validation:
- Whitelist mechanism: Allowing only specific domains and protocols
- Deep URL parsing: Extracting the actual host of the request to prevent parsing discrepancies
- Disabling uncommon protocols (file, gopher, dict, etc.)
-
Network Layer Protection:
- Setting network access policies to restrict server outbound connections
- Using intermediary proxies for request forwarding to enforce security checks
- Configuring firewall rules to block access to internal network segments and metadata services
-
Application Layer Protection:
- Implementing authentication mechanisms to ensure SSRF requests do not escalate privileges
- Setting request timeouts to prevent port scanning exploitation
- Performing security checks on response content to avoid data leakage
6. Protection Code Example
import requests
from urllib.parse import urlparse
def safe_fetch_url(url):
# Parse URL to obtain host
parsed = urlparse(url)
hostname = parsed.hostname
# Internal IP blacklist
internal_ips = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
cloud_metadata = ['169.254.169.254', 'metadata.google.internal']
# Check if the address is internal
if is_internal_ip(hostname, internal_ips) or hostname in cloud_metadata:
raise Exception("Access to internal resources is prohibited")
# Protocol whitelist
if parsed.scheme not in ['http', 'https']:
raise Exception("Unsupported protocol")
# Initiate request
response = requests.get(url, timeout=5, allow_redirects=False)
return response.content
def is_internal_ip(hostname, internal_ranges):
# Implementation of internal IP range check
# Detailed implementation requires converting hostname to IP and checking if it falls within internal ranges
pass
7. Summary
The risk posed by SSRF vulnerabilities has become increasingly severe with the widespread adoption of cloud-native architectures. Effective protection requires a multi-layered defense approach combining input validation, network isolation, and secure configurations. Implementing strict whitelist validation at the code level and restricting server network access permissions at the architectural level are fundamental to mitigating SSRF risks.