Server Side Request Forgery ('SSRF')
ID |
python.server_side_request_forgery |
Severity |
critical |
Resource |
Channel |
Language |
Python |
Tags |
CWE:918, NIST.SP.800-53, OWASP:2021:A10, PCI-DSS:6.5.8 |
Description
Improper validation of external input used to retrieve the content of a URL ('SSRF').
SSRF vulnerabilities arise when an application accepts user input to create or control URLs or networking requests without appropriate validation or restriction. This can allow attackers to craft malicious requests to sensitive internal endpoints or external services on behalf of the server.
Rationale
Similar to other injection attacks, an SSRF vulnerability allows an attacker to manipulate the URLs used by a server-side application, to point to unexpected internal or external resources.
By carefully selecting the URLs, the attacker can read or update internal resources, such as cloud metadata, internal services, or databases. In addition, SSRF can bypass network access controls like firewalls and VPNs.
An SSRF vulnerability can be exploited by threat actors for network reconnaissance, data exfiltration, denial of service or pivot attacks to other systems.
For instance, consider a Python application that fetches resources based on user-provided URLs:
import requests
from flask import Flask, request
app = Flask(__name__)
@app.route('/fetch')
def fetch_data():
target_url = request.args.get('target')
# Unsafely using user input for server-side request
response = requests.get(target_url)
return response.content
Remediation
To prevent SSRF vulnerabilities in applications, follow these remediation practices:
-
Input Validation and Whitelisting: Always sanitize and validate user-supplied data in URLs using a whitelist of known, safe URLs. Reject any URLs not meeting established criteria to limit exposure to external or unauthorized internal requests.
-
Use a Proxy or Gateway Approach: Route all outbound requests through a proxy or gateway, allowing finer control over which requests should be allowed and logged.
-
Network Segmentation and Firewalls: Implement network segmentation to restrict the application’s ability to access sensitive internal services. Use firewalls to block traffic by default and allow only specific, necessary requests.
-
Monitoring and Logging: Implement comprehensive request logging and monitoring solutions to detect suspicious outbound requests indicative of SSRF attempts.
By following these recommended practices, applications can effectively defend against SSRF vulnerabilities, ensuring that server-side requests are controlled and properly secured from unauthorized exploitation.
A sanitized version of the previous example would look like this:
import requests
from urllib.parse import urlparse
from flask import Flask, request
app = Flask(__name__)
ALLOWED_DOMAINS = ['example.com', 'trustedsource.com']
@app.route('/fetch')
def fetch_data():
target_url = request.args.get('target')
parsed_url = urlparse(target_url)
# Validate the domain of the target URL
if parsed_url.hostname not in ALLOWED_DOMAINS:
return 'Invalid target URL!', 400
# Perform the request
response = requests.get(target_url)
return response.content
Configuration
The detector has the following configurable parameters:
-
sources
, that indicates the source kinds to check. -
neutralizations
, that indicates the neutralization kinds to check.
Unless you need to change the default behavior, you typically do not need to configure this detector.
References
-
CWE-918 : Server-Side Request Forgery (SSRF).
-
OWASP - Top 10 2021 Category A10 : Server-Side Request Forgery (SSRF).
-
Server-Side Request Forgery Prevention Cheat Sheet, in OWASP Cheat Sheet Series.