PHP SSRF
URL-aware PHP functions
When URL-aware wrappers are enabled, functions such as file_get_contents(), fopen(), file(), and md5_file() can accept remote URLs. Passing an attacker-controlled URL to them without validating its resolved destination can create an SSRF vulnerability.[1]
file_get_contents("http://127.0.0.1:8081");
fopen("http://127.0.0.1:8081", "r");
file("http://127.0.0.1:8081");
md5_file("http://127.0.0.1:8081");
WordPress SSRF via DNS rebinding
Patchstack demonstrated that WordPress’s wp_safe_remote_get() checks could be bypassed with DNS rebinding in the versions they tested. The validation path called wp_http_validate_url() before the connection, allowing a hostname to resolve to an allowed address during validation and a different address during the request.[2] Treat this as version-dependent research: verify the exact WordPress and HTTP-library versions before reproducing it.
The same research identified the following callers or wrappers as potentially affected:[2]
wp_safe_remote_request()wp_safe_remote_post()wp_safe_remote_head()WP_REST_URL_Details_Controller::get_remote_url()download_url()wp_remote_fopen()WP_oEmbed::discover()
Historical CRLF header injection
PHP bug #81680 documented CRLF injection through the from INI setting used by the HTTP stream wrapper. The behavior is version-dependent and should not be assumed on a patched runtime.[3]
// The following creates a From header and injects an additional header.
ini_set("from", "Hi\r\nInjected: I HAVE IT");
file_get_contents("http://127.0.0.1:8081");
GET / HTTP/1.1
From: Hi
Injected: I HAVE IT
Host: 127.0.0.1:8081
Connection: close
[!WARNING] Test header-injection behavior only against an isolated target: the example sends attacker-controlled HTTP headers to the destination.
Separately, stream contexts intentionally support setting request headers. This is not itself a vulnerability, but it becomes dangerous when an application copies untrusted input into the header string.[4]
$url = "https://example.com/";
$options = [
'http' => [
'method' => 'GET',
'header' => "Accept-Language: en\r\n" .
"Cookie: foo=bar\r\n" .
"User-Agent: SecurityTestClient/1.0\r\n",
],
];
$context = stream_context_create($options);
$file = file_get_contents($url, false, $context);