1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
From 2037761bc8aa5101e086a98a3f6db8acdbc051f1 Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Fri, 8 Nov 2024 23:43:47 +0100
Subject: [PATCH 1/6] Fix GHSA-c5f2-jwm7-mmq2: stream HTTP fulluri CRLF
injection
(cherry picked from commit 426a6d4539ebee34879ac5de857036bb6ff0e732)
(cherry picked from commit bc1f192102dd8cbda028e40aa31604c4885d387c)
(cherry picked from commit 8d130e16fbfda7d154fedfa0f1ff1d5ad5e26815)
(cherry picked from commit 494de65139592da0e5e5b6fdf198c2f9c762f4d6)
(cherry picked from commit dcb89ed9d0217510f3906ce0c517f704e6bd80dc)
(cherry picked from commit 11787051a17d2fcea427cd66c3fcc5e99ab94a03)
(cherry picked from commit 59bfc165234a2bb79916c340cd98d011deedc995)
(cherry picked from commit 8dab7d0bb9c4133a082c70403af0c6a4c1b0025b)
(cherry picked from commit da023a8118592bd62fa768e83c2a7b52deaa3689)
---
ext/standard/http_fopen_wrapper.c | 29 +++++++++++--------
.../tests/http/ghsa-c5f2-jwm7-mmq2.phpt | 28 ++++++++++++++++++
2 files changed, 45 insertions(+), 12 deletions(-)
create mode 100644 ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 78bd935a0e..157ffd718f 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -178,6 +178,16 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
return NULL;
}
+ /* Should we send the entire path in the request line, default to no. */
+ if (context && php_stream_context_get_option(context, "http", "request_fulluri", &tmpzval) == SUCCESS) {
+ zval ztmp = **tmpzval;
+
+ zval_copy_ctor(&ztmp);
+ convert_to_boolean(&ztmp);
+ request_fulluri = Z_BVAL(ztmp) ? 1 : 0;
+ zval_dtor(&ztmp);
+ }
+
use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
/* choose default ports */
if (use_ssl && resource->port == 0)
@@ -197,6 +207,13 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
}
}
+ if (request_fulluri && (strchr(path, '\n') != NULL || strchr(path, '\r') != NULL)) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper full URI path does not allow CR or LF characters");
+ php_url_free(resource);
+ efree(transport_string);
+ return NULL;
+ }
+
if (context && php_stream_context_get_option(context, wrapper->wops->label, "timeout", &tmpzval) == SUCCESS) {
SEPARATE_ZVAL(tmpzval);
convert_to_double_ex(tmpzval);
@@ -382,18 +399,6 @@ finish:
strncpy(scratch, "GET ", scratch_len);
}
- /* Should we send the entire path in the request line, default to no. */
- if (!request_fulluri &&
- context &&
- php_stream_context_get_option(context, "http", "request_fulluri", &tmpzval) == SUCCESS) {
- zval ztmp = **tmpzval;
-
- zval_copy_ctor(&ztmp);
- convert_to_boolean(&ztmp);
- request_fulluri = Z_BVAL(ztmp) ? 1 : 0;
- zval_dtor(&ztmp);
- }
-
if (request_fulluri) {
/* Ask for everything */
strcat(scratch, path);
diff --git a/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt b/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt
new file mode 100644
index 0000000000..6e68f67654
--- /dev/null
+++ b/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt
@@ -0,0 +1,28 @@
+--TEST--
+GHSA-c5f2-jwm7-mmq2 (Configuring a proxy in a stream context might allow for CRLF injection in URIs)
+--INI--
+allow_url_fopen=1
+--CONFLICTS--
+server
+--FILE--
+<?php
+$serverCode = <<<'CODE'
+echo $_SERVER['REQUEST_URI'];
+CODE;
+
+include __DIR__."/../../../../sapi/cli/tests/php_cli_server.inc";
+php_cli_server_start($serverCode, null);
+
+$host = PHP_CLI_SERVER_ADDRESS;
+$userinput = "index.php HTTP/1.1\r\nHost: $host\r\n\r\nGET /index2.php HTTP/1.1\r\nHost: $host\r\n\r\nGET /index.php";
+$context = stream_context_create(['http' => ['proxy' => 'tcp://' . $host, 'request_fulluri' => true]]);
+echo file_get_contents("http://$host/$userinput", false, $context);
+?>
+--EXPECTF--
+Warning: file_get_contents(http://localhost:%d/index.php HTTP/1.1
+Host: localhost:%d
+
+GET /index2.php HTTP/1.1
+Host: localhost:%d
+
+GET /index.php): failed to open stream: HTTP wrapper full URI path does not allow CR or LF characters in %s on line %d
--
2.47.0
|