<?php
function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
switch($notification_code) {
case STREAM_NOTIFY_MIME_TYPE_IS:
echo "Found the mime-type: ", $message, PHP_EOL;
break;
}
}
$ctx = stream_context_create();
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
var_dump(file_get_contents("http://127.0.0.1:8080", false, $ctx));
var_dump($http_response_header);
printf "HTTP/1.0 200 Ok\r\nContent-Type: text/html;\r\n charset=utf-8\r\n\r\nbody\r\n" |nc -l 0.0.0.0 8080
Found the mime-type: text/html;
string(6) "body
"
array(3) {
[0]=>
string(15) "HTTP/1.0 200 Ok"
[1]=>
string(24) "Content-Type: text/html;"
[2]=>
string(17) " charset=utf-8"
}
Summary
The header parser of the
http
stream wrapper does not handle folded headers and passes incorrect MIME types to an attached stream notifier.Details
The header parser of the
http
stream parser does not understand that a header line beginning with whitespace continues the previous header and instead considers every newline to be a header separator.This has two consequences:
STREAM_NOTIFY_MIME_TYPE_IS
notification might report an incorrect MIME type, if thecontent-type
header is a folded header.$http_response_header
array contains the header continuation lines as they appear on-the-wire, requiring userland code to be aware of folded headers and violating RFC9112#5.2, which specifies:PoC
Running against:
results in:
being printed (after killing
nc
with Ctrl+C), thus missing thecharset
within the mime type.Impact
Users of the
http
stream wrapper might interpret the response with an incorrect MIME type and more generally might misparse the response, for example by incorrectly determining which response headers belong to the final response if a redirect happened.