Skip to content

Commit

Permalink
Merge branch 'PHP-7.3' into PHP-7.4
Browse files Browse the repository at this point in the history
* PHP-7.3:
  Fixes #79265: Improper injection of Host header when using fopen for http requests
  • Loading branch information
nikic committed Feb 24, 2020
2 parents 09e7c86 + d0d6050 commit e855b28
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 28 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ PHP NEWS

- Standard:
. Fixed bug #79254 (getenv() w/o arguments not showing changes). (cmb)
. Fixed bug #79265 (Improper injection of Host header when using fopen for
http requests). (Miguel Xavier Penha Neto)

?? ??? ????, PHP 7.4.3

Expand Down
91 changes: 63 additions & 28 deletions ext/standard/http_fopen_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,41 +459,76 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
strip_header(user_headers, t, "content-type:");
}

if ((s = strstr(t, "user-agent:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_USER_AGENT;
s = t;
while ((s = strstr(s, "user-agent:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_USER_AGENT;
break;
}
s++;
}
if ((s = strstr(t, "host:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_HOST;

s = t;
while ((s = strstr(s, "host:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_HOST;
break;
}
s++;
}
if ((s = strstr(t, "from:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_FROM;

s = t;
while ((s = strstr(s, "from:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_FROM;
break;
}
if ((s = strstr(t, "authorization:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_AUTH;
s++;
}
if ((s = strstr(t, "content-length:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_CONTENT_LENGTH;

s = t;
while ((s = strstr(s, "authorization:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_AUTH;
break;
}
s++;
}
if ((s = strstr(t, "content-type:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_TYPE;

s = t;
while ((s = strstr(s, "content-length:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_CONTENT_LENGTH;
break;
}
s++;
}
if ((s = strstr(t, "connection:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_CONNECTION;

s = t;
while ((s = strstr(s, "content-type:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_TYPE;
break;
}
s++;
}

s = t;
while ((s = strstr(s, "connection:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_CONNECTION;
break;
}
s++;
}

/* remove Proxy-Authorization header */
if (use_proxy && use_ssl && (s = strstr(t, "proxy-authorization:")) &&
(s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
Expand Down
39 changes: 39 additions & 0 deletions ext/standard/tests/http/bug79265.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
--TEST--
Bug #79265 (Improper injection of Host header when using fopen for http requests)
--INI--
allow_url_fopen=1
--SKIPIF--
<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?>
--FILE--
<?php
require 'server.inc';

$responses = array(
"data://text/plain,HTTP/1.0 200 OK\r\n\r\n",
);

$pid = http_server("tcp://127.0.0.1:12342", $responses, $output);

$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"RandomHeader: localhost:8080\r\n" .
"Cookie: foo=bar\r\n" .
"Host: userspecifiedvalue\r\n"
)
);
$context = stream_context_create($opts);
$fd = fopen('http://127.0.0.1:12342/', 'rb', false, $context);
fseek($output, 0, SEEK_SET);
echo stream_get_contents($output);
fclose($fd);

http_server_kill($pid);

?>
--EXPECT--
GET / HTTP/1.0
Connection: close
RandomHeader: localhost:8080
Cookie: foo=bar
Host: userspecifiedvalue

0 comments on commit e855b28

Please sign in to comment.