CVE-2026-91766
Credential disclosure via cross-origin HTTP redirects
| Publication Date | 2026-09-25 |
|---|---|
| Severity | Moderate |
| Type | Privilege Escalation |
| Affected PHP Versions |
|
| Fixed Product Versions |
|
CVE Details
When the http:// stream wrapper follows a redirect, it forwards the user-supplied Authorization, Cookie and Proxy-Authorization headers unchanged, even when the redirect target is a different host, a different port, or a downgrade from HTTPS to HTTP. A server that can steer a redirect therefore receives credentials that were only meant for the original origin. A malicious server capable of steering redirects can exploit this flaw to capture sensitive credentials intended only for the original destination.
Recommendations
Consider switching to cURL for making HTTP requests, instead of using the HTTP stream wrapper. If you cannot, consider manually following redirects and stripping these headers on any redirect:
function fetch(string $url, array $headers, int $maxRedirects = 5): string|false
{
$origin = static fn (string $u): string => (static function (array $p): string {
$port = $p['port'] ?? ($p['scheme'] === 'https' ? 443 : 80);
return strtolower("{$p['scheme']}://{$p['host']}:{$port}");
})(parse_url($u));
$startOrigin = $origin($url);
for ($i = 0; $i <= $maxRedirects; $i++) {
$sendHeaders = $headers;
if ($origin($url) !== $startOrigin) {
$sendHeaders = array_filter(
$headers,
fn ($h) => ! preg_match('/^(authorization|cookie|proxy-authorization):/i', $h)
);
}
$ctx = stream_context_create(['http' => [
'header' => implode("\r\n", $sendHeaders),
'follow_location' => 0,
'ignore_errors' => true,
]]);
$body = file_get_contents($url, false, $ctx);
$status = (int) substr($http_response_header[0] ?? '', 9, 3);
if ($status < 300 || $status >= 400) {
return $body;
}
foreach ($http_response_header as $h) {
if (stripos($h, 'Location:') === 0) {
// Note: resolve relative Location values against $url before using
$url = trim(substr($h, 9));
continue 2;
}
}
return $body;
}
return false;
}
If you are using the HTTP stream wrapper in PHP, and send Authorization, Cookie, and/or Proxy-Authentication headers, we recommend updating to a patched version of PHP.