PHP curl_exec() url is controlled by user
Description
This vulnerability occurs when user-supplied input is used to construct the URL parameter for PHP's curl_exec() function without proper validation. Allowing users to control the target URL enables Server-Side Request Forgery (SSRF) attacks, where attackers can force the server to make requests to unintended destinations. Attackers can exploit this by using protocol handlers such as file:// to read local files (e.g., file:///etc/passwd), or by targeting internal network resources behind firewalls using URLs like http://192.168.0.1 or ftp://192.168.0.1. In systems with older libcurl versions supporting SCP, specially crafted URLs containing embedded commands (e.g., scp://name:passwd@host/a'``;date >/tmp/test``;') may lead to arbitrary command execution on the target server.
Remediation
Implement the following security controls to prevent user manipulation of curl URLs:
1. Use a URL Whitelist: Define an explicit list of allowed destination URLs or domains and validate all user input against this list before making requests.
$allowed_domains = ['api.trusted-site.com', 'data.partner.com'];
$parsed_url = parse_url($user_input);
if (!in_array($parsed_url['host'], $allowed_domains)) {
die('Invalid destination');
}2. Restrict Protocol Handlers: Configure curl to only allow safe protocols (http/https) and explicitly disable dangerous ones.
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
3. Avoid Direct User Input: Never pass user input directly to curl_setopt() for CURLOPT_URL. Instead, use user input as an identifier to select from predefined URLs.
$url_map = [
'resource1' => 'https://api.example.com/data1',
'resource2' => 'https://api.example.com/data2'
];
$resource_id = $_GET['resource'];
if (isset($url_map[$resource_id])) {
curl_setopt($ch, CURLOPT_URL, $url_map[$resource_id]);
}4. Implement Network-Level Controls: Configure firewall rules to restrict outbound connections from the web server to only necessary external services and block access to internal IP ranges (RFC 1918 addresses).