CWE-918: Server-Side Request Forgery (SSRF)
Learn about CWE-918 (Server-Side Request Forgery (SSRF)), its security impact, exploitation methods, and prevention guidelines.
What is Server-Side Request Forgery (SSRF)?
• Overview: Server-Side Request Forgery (SSRF) occurs when a web server receives a URL or similar request from an upstream component and retrieves the contents of the URL without ensuring the request is sent to the intended destination.
• Exploitation Methods:
- Attackers can manipulate input URLs to make the server request internal resources.
- Common attack patterns include accessing internal systems, cloud metadata services, or local files.
• Security Impact:
- Direct consequences include unauthorized access to internal resources and data leakage.
- Potential cascading effects involve further exploitation of the internal network, such as pivoting to other systems.
- Business impact can involve data breaches, compliance violations, and financial loss.
• Prevention Guidelines:
- Specific code-level fixes include validating and sanitizing input URLs to restrict requests to trusted origins.
- Security best practices involve implementing allow-lists for outbound requests and employing network segmentation.
- Recommended tools and frameworks include using web application firewalls (WAFs) and network security monitoring tools to detect and block malicious requests.
Technical Details
Likelihood of Exploit: Not specified
Affected Languages: Not Language-Specific
Affected Technologies: Web Server
Vulnerable Code Example
Python Example
import requests
from flask import Flask, request
app = Flask(__name__)
@app.route('/fetch')
def fetch_url():
url = request.args.get('url') # User input is directly used to fetch URL contents
response = requests.get(url) # No restriction on the URL being fetched
return response.content # Returned content can include sensitive data
if __name__ == '__main__':
app.run()
Explanation:
- Lines 10-12: The application takes a URL from user input and directly uses it to make an HTTP request. There is no validation or restriction on the URL, which can lead to SSRF attacks. An attacker could exploit this to make requests to internal services or unauthorized endpoints, potentially exposing sensitive data or causing other security issues.
How to fix Server-Side Request Forgery (SSRF)?
Fixed Code Example
import requests
from flask import Flask, request
from urllib.parse import urlparse
app = Flask(__name__)
# Define a list of allowed domains
ALLOWED_DOMAINS = {'example.com', 'api.example.com'}
@app.route('/fetch')
def fetch_url():
url = request.args.get('url')
parsed_url = urlparse(url)
# Check if the domain is in the allowed list
if parsed_url.hostname not in ALLOWED_DOMAINS:
return "Domain not allowed", 403
# Ensure the URL scheme is HTTP or HTTPS
if parsed_url.scheme not in {'http', 'https'}:
return "Invalid URL scheme", 400
try:
# Perform the request only if the checks pass
response = requests.get(url)
return response.content
except requests.exceptions.RequestException as e:
return f"Request failed: {e}", 500
if __name__ == '__main__':
app.run()
Explanation:
- Line 12: The application parses the URL to extract components, which are then validated.
- Line 13: The domain of the user-provided URL is checked against a whitelist, blocking unauthorized domains.
- Line 14: The URL scheme is verified to ensure it's either HTTP or HTTPS, preventing the use of unexpected protocols.
- Line 15: The request is made only after all validations pass, significantly reducing the risk of SSRF attacks.
By implementing domain whitelisting, input validation, and URL scheme checks, the application is better protected against SSRF vulnerabilities.