summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-02-24 09:50:57 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-02-24 09:51:36 +0100
commite855b286c87071ae4c00004ccefabb771102ccb1 (patch)
treeb5d27e60b0b4e36e606c7774199ecec00b59de55 /ext/standard
parent09e7c86779b281c3d1fbff5954fbb9e0b052cf33 (diff)
parentd0d60503b54b528d42546acf1ca34914fb8aea55 (diff)
downloadphp-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.c91
-rw-r--r--ext/standard/tests/http/bug79265.phpt39
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