diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-02-24 09:50:57 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-02-24 09:51:36 +0100 |
commit | e855b286c87071ae4c00004ccefabb771102ccb1 (patch) | |
tree | b5d27e60b0b4e36e606c7774199ecec00b59de55 /ext/standard | |
parent | 09e7c86779b281c3d1fbff5954fbb9e0b052cf33 (diff) | |
parent | d0d60503b54b528d42546acf1ca34914fb8aea55 (diff) | |
download | php-git-e855b286c87071ae4c00004ccefabb771102ccb1.tar.gz |
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
Fixes #79265: Improper injection of Host header when using fopen for http requests
Diffstat (limited to 'ext/standard')
-rw-r--r-- | ext/standard/http_fopen_wrapper.c | 91 | ||||
-rw-r--r-- | ext/standard/tests/http/bug79265.phpt | 39 |
2 files changed, 102 insertions, 28 deletions
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 9632bd344e..ffdb53ccbf 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -459,41 +459,76 @@ finish: 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' || diff --git a/ext/standard/tests/http/bug79265.phpt b/ext/standard/tests/http/bug79265.phpt new file mode 100644 index 0000000000..4848991bd0 --- /dev/null +++ b/ext/standard/tests/http/bug79265.phpt @@ -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 |