Sec Bug->Bug #81690 [Opn]: A request smuggling in file_get_contents

From: 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

« previous php.bugs (#238451) next »