php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80385 Response data preceded by post data
Submitted: 2020-11-20 04:23 UTC Modified: 2021-04-29 13:34 UTC
Votes:19
Avg. Score:4.6 ± 0.8
Reproduced:18 of 18 (100.0%)
Same Version:5 (27.8%)
Same OS:3 (16.7%)
From: 306503207 at qq dot com Assigned: bukka (profile)
Status: Re-Opened Package: FPM related
PHP Version: 7.2.34 OS: CentOS 7.4
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
20 + 8 = ?
Subscribe to this entry?

 
 [2020-11-20 04:23 UTC] 306503207 at qq dot com
Description:
------------
PHP-fpm runs stably, but after a period of time, the post data is automatically added to the response data. After restarting PHP-fpm, the response is correct. After a period of time, this problem occurs again


Expected result:
----------------
request data:page=1&rows=20
response data:
{response data}

Actual result:
--------------
page=1&rows=20{response data}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-11-20 07:18 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2020-11-20 07:18 UTC] requinix@php.net
Not enough information was provided for us to be able
to handle this bug. Please re-read the instructions at
http://bugs.php.net/how-to-report.php

If you can provide more information, feel free to add it
to this bug and change the status back to "Open".

Thank you for your interest in PHP.


 [2020-11-21 09:33 UTC] 306503207 at qq dot com
-Status: Feedback +Status: Open
 [2020-11-21 09:33 UTC] 306503207 at qq dot com
When this happens, rockmongo installed on the same machine has the same problem. After restarting PHP FPM, the response is correct. I met some people in a discussion group. Have you ever recorded such a bug.
 [2020-11-21 18:59 UTC] shoebox at dnbradio dot com
I can confirm the same issue is happening with my PHP-FPM instance. I have tested all the way up to 7.4 and the problem persists.

Steps to reproduce.
1. Create script called /test.php with code <?php echo "foo"; ?>
2. Make a POST request with post params bar=1 via x-www-form-urlencoded or raw to a PHP endpoint over http.

Expected Result:
Response body should be "foo"

Actual Result:
Response body includes post params prepended to the HTTP response.
i.e. "bar=1test"
 [2020-11-22 21:32 UTC] shoebox at dnbradio dot com
I thought perhaps this was caused by a misconfiguration but I found that even if I explicitly set auto_prepend_file = none, the problem persists.

I have tested by creating a php script <?php phpinfo(); ?> and when I refresh the page over and over I see the auto_prepend_file setting keeps changing back and forth from none to php://input

Here is a screen cap demonstrating the problem: https://www.dropbox.com/s/2kofxya97gmydpi/Nov-22-2020%2014-17-58.mp4?dl=0
 [2020-11-22 22:18 UTC] requinix@php.net
I find it highly unlikely that PHP itself is randomly deciding to set auto_prepend_file to php://input.
Compare the phpinfo outputs from the two different pages - are they perhaps using different php-fpm pools or configurations?
 [2020-11-22 23:13 UTC] shoebox at dnbradio dot com
Well I would agree with you that this is highly unlikely, but these are not 2 different php pages. It is a single php page that I am refreshing and you can watch the value change from "none" to "php://input" just by refreshing the page. 

There is nothing special about the configuration. It is a base install of php-fpm running on a docker container with nginx setup as a standard reverse proxy.  I have even tried using ini_set("auto_prepend_file","none"); at the top of my script but the phpinfo() output shows auto_prepend_file changing on its own.
 [2020-11-22 23:48 UTC] requinix@php.net
Right, by "page" I meant the different refreshes of the page in the browser.
If the auto_prepend_file is different then maybe other things are different. Compare the phpinfo outputs.
 [2020-11-23 03:56 UTC] 306503207 at qq dot com
After restarting PHP-fpm, the response is correct. After a period of time, this problem occurs again.In your issue, does it work to restart php-fpm?
 [2020-11-23 04:11 UTC] 306503207 at qq dot com
https://bugs.php.net/bug.php?id=80378
content-type: application/octet-stream

Maybe this bug is also caused by this situation.
 [2020-11-23 08:32 UTC] 306503207 at qq dot com
I update to PHP-7.3.23, but problems still arise.
 [2020-11-23 18:24 UTC] shoebox at dnbradio dot com
Here is side-by-side comparison of phpinfo() where 2 impacting config settings are being toggled on and off between page refreshes.

https://www.dropbox.com/s/9ae2pqi2nffchog/screen%20shot%202020-11-23%20at%2011.18.40%20am.png?dl=0

Settings being toggled are:
auto_prepend_file
allow_url_include

These settings are explicitly set to "none" in /usr/local/etc/php/php.ini however php seemingly is toggling these settings to On or php://input by itself.

Restarting the server fixes the issue for some time.

I tried various php-fpm versions. This is happening in 7.2, 7.3, 7.4
 [2020-11-23 18:39 UTC] shoebox at dnbradio dot com
I'm now wondering if this could be caused by a bug in one of the php modules so I am disabling them for now. I suspect this could be caused by the mongo module since the OP mentioned something mongo-related in their original report.  Here is my Docker file showing all modules I have currently enabled. I will disable all of these to see if the problem persists.

FROM php:7.4-fpm
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libssl-dev \
        libpng-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libmagickwand-dev --no-install-recommends \
        zip \
        unzip \
        git-all \
        libaspell-dev \
        mariadb-client --no-install-recommends \
    && docker-php-ext-install pdo_mysql \
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    && docker-php-ext-configure gd \
      --with-freetype \
      --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd \
    && pecl install mongodb \
    && docker-php-ext-enable mongodb \
    && pecl install mailparse \
    && docker-php-ext-enable mailparse
 [2020-11-23 19:06 UTC] requinix@php.net
This may very well be my imagination getting the best of me, but seeing a configuration with allow_url_include=on and auto_prepend_file=input, that's the sort of thing I would attribute to a hack. Because with those enabled, someone can run PHP code on your server without having to compromise any application files. Though there is normally some sort of trigger to get that behavior - it randomly happening would break stuff and draw attention to the problem.

Have you looked into that sort of possibility? Do you have access logs you can check to see if there's anything suspicious? Are your php-fpm pools configured securely? Any unauthorized file changes?

And when you compared phpinfo outputs, did you compare the *entire* output? Everything from the configure command to the extension settings?
 [2020-11-23 19:43 UTC] shoebox at dnbradio dot com
re: phpinfo() -- yes I did a diff on the full phpinfo() output. I trimmed it down in my previous post so that it would fit within a single screenshot.

re: hack, I thought the same thing; but given that this is an isolated freshly built container I am thinking that's not the case. I've setup firewall so that no outside traffic besides my own IP can hit the server but the issue still reoccurred. I will try testing on a local machine deployment as well from a freshly built container. 

re:pools -- no additional pool configuration is added. There is only a single app running on this container and running on this host. I'll look further into this.
 [2020-11-23 23:51 UTC] dano at fashionphile dot com
We are getting the exact same problem since 11/13/2020 we have started getting the exact same issue. We are on php 7.3.24 currently. We have narrowed this issue down to only post requests and whenever we restart PHP-fpm it solves the issue for about an hour of time, then continues again.
 [2020-11-24 04:20 UTC] 306503207 at qq dot com
检测到中文(简体)
英语
通用领域
生物医药

I think PHP was attacked. I can reproduce this situation. For example, by using nginx, the configuration parameters can modify the PHP configuration. The configuration is as follows:

#fastcgi_param PHP_VALUE "auto_prepend_file= php://input \n auto_append_file= php://input ";

#fastcgi_param PHP_ADMIN_VALUE "allow_url_include=On";

How can I close PHP_ADMIN_VALUE of parameter?
 [2020-11-24 04:25 UTC] 306503207 at qq dot com
How to configure PHP FPM pool security
 [2020-12-01 22:21 UTC] maxime dot mazouth-laurol at hotmail dot fr
Did someone find a solution for this issue ? 
I have the same with php:7.2-fpm docker container named "engine" from now on.

Even if the POST data prepends the response, I keep getting none values from php.ini :
* linux command : docker-compose exec engine php -i | grep prepend
* output        : auto_prepend_file => no value => no value

* linux command : docker-compose exec engine php -i | grep url_include
* output        : allow_url_include => Off => Off
 [2020-12-02 00:44 UTC] requinix@php.net
There are quite a few variables and moving parts here. Can someone upload/link to a small but complete repro somewhere? Like with a Dockerfile or two, maybe docker-compose file, and test script?
 [2020-12-03 20:25 UTC] maxime dot mazouth-laurol at hotmail dot fr
I would be glad to do so, but I can't...

The reason ? I have the exact same docker container (php7.2-fpm) on a remote debian server and locally under ubuntu but : 
* the problem appears on the debian server  (Debian GNU/Linux 9.8 stretch)
* the problem does not appear on my ubuntu 18.04 local machine, so I cannot reproduce it..

Then, one could logically think that the root cause is not in the docker container itself.
But if I restart the docker container, the issue disappears for some time, so it is container related.
 [2020-12-03 23:42 UTC] requinix@php.net
Even if it isn't strictly the container at fault, even if it ends up being an issue with Docker or Debian or something else, if the container on Debian reproduces then that's at least a starting point to look into it further.
 [2020-12-09 11:28 UTC] shoebox at dnbradio dot com
This is not a fix to the bug report but this is how I am working around the issue.  I'm now using nginx with mod_security enabled (wodby/nginx has mod_security built-in), and I have my default host and location on nginx pointing to a static html page rather than php so that the attacker cannot access the php location without using a domain name defined in the nginx config. With the previous configuration an attacker was able to hit php-fpm by just going to the ip address. I have not seen the problem return, however I am unsure if nginx with mod_security defaults is still vulnerable to the same exploit. Additional configuration and filters may need to be applied.
 [2020-12-28 19:22 UTC] bukka@php.net
So this is specifically documented in https://www.php.net/manual/en/install.fpm.configuration.php . See the "Example #2 set PHP settings in nginx.conf" and the warning below that "php-fpm should not be bound to a worldwide accessible address". So if the FPM is publicly available, it should at least have listen.allowed_clients set so only the server can connect to it.

This looks like the reason why this got reported (setting PHP_VALUE and PHP_ADMIN_VALUE) from the OP comments. Does anyone see this behaviour when having fpm protected?

Also it's not the first time I'm seeing a report like this so I'm thinking to introduce some options that would disallow this.
 [2020-12-28 19:23 UTC] bukka@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: bukka
 [2021-01-10 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2021-02-09 14:28 UTC] benedikt dot schaller at simovative dot com
Same problem here with Ubuntu 16.04 and PHP7.3 over apache fast-cgi module and php-fpm. The problem apears if the fpm service runs for some time and is gone after a php-fpm restart.

I think that is a big security issue, because you could execute php code.

We have a log of similiar systems and it only happens on one of them. There themes to be no difference.
 [2021-02-27 05:16 UTC] wjh08081329 at gmail dot com
when i run use docker php:8.0.1 ,i encounter this issue, but when i start a container with a self defined php.ini locate in  /usr/local/etc/php/ which with auto_prepend_file is no value ,the issue is gone
 [2021-03-01 07:52 UTC] camalolo at gmail dot com
Having the same exact issue. Php 7.3.27 / Ubuntu 20.04
 [2021-03-01 09:22 UTC] requinix@php.net
-Status: No Feedback +Status: Re-Opened -Assigned To: bukka +Assigned To:
 [2021-03-19 10:13 UTC] en3py at hotmail dot com
Having the same issue on two different deployments:

CentOS 7.9
CentOS 8.3

The problem does not appear on a CentOS 7.3

PHP compiled from source (7.2.34) with the following string:

./configure --prefix=/opt/php/7.2 \
	--exec-prefix=/opt/php/7.2 \
	--bindir=/opt/php/7.2/bin \
	--sbindir=/opt/php/7.2/sbin \
	--datadir=/opt/php/7.2/share \
	--includedir=/opt/php/7.2/include \
	--libdir=/opt/php/7.2/lib64 \
	--localstatedir=/var \
	--sharedstatedir=/var/lib \
	--sysconfdir=/etc/php/7.2 \
	--mandir=/usr/share/man \
	--infodir=/usr/share/info \
	--with-config-file-path=/etc/php/7.2 \
	--with-config-file-scan-dir=/etc/php/7.2/conf.d \
	--with-openssl-dir=/opt/openssl \
	--disable-cgi --enable-ftp --enable-mbstring --enable-mysqlnd --with-curl --with-zlib \
	--enable-fpm --with-fpm-user=apache --with-fpm-group=nobody --with-pdo-mysql \
	--enable-zip --with-mysqli --enable-embedded-mysqli \
	--with-openssl --with-ldap


FPM configuration for this context:

[xxx]
user = xxx
group = nobody
listen = 0.0.0.0:17202
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.process_idle_timeout = 10s;
pm.status_path = /status

access.log = /var/log/fpm-7.2-$pool.access.log
access.format = "%R %{HTTP_HOST}e - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"

slowlog = /var/log/php-7.2.$pool.slow.log
request_slowlog_timeout = 10s
request_slowlog_trace_depth = 20

php_admin_value[include_path] = ".:/opt/xxx/lib:/opt/php-7.2/lib64/php"
php_admin_flag[display_errors] = false
php_admin_value[session.name] = "xxx-staging"
php_admin_value[session.save_path] = "/opt/xxx/sessions"
php_admin_flag[session.auto_start] = true


From our experience this is what happens:

- the worker starts
- POST any form: everything seems right
- avoid making any call for 5-10 seconds
- POST THE SAME Form: response data is prepended to any output

The problem persists even if the target of the POST form is empty.


[19/Mar/2021:10:10:25 +0000] "POST /it/about/op-flag.php HTTP/1.1" 200 86 [omissis]
[19/Mar/2021:10:10:26 +0000] "POST /it/about/op-flag.php HTTP/1.1" 200 201 [omissis]

The first row (Apache HTTPD 2.4.46) has the correct output, while the second shows the prepended results, so it really comes out from FPM.

We are still investigating the isse, whereas we have about 10 servers created last year with the identical configuration and the problem seems not occurring...
 [2021-03-19 17:13 UTC] en3py at hotmail dot com
We digged a bit more in the problem and got the following details.

As someone mentioned, the issue seems to reside in the auto_prepend_file directive of the file.

So here is how we did reproduce the problem:

The php.ini file had the following settings:

auto_prepend_file = ""
allow_url_fopen = Off
allow_url_include = 0

Note that even setting to "Off" the allow_url_include directive, in the phpinfo() output it was still set to "On".

To reproduce the problem:

1. open the page with phpinfo() output. In Core section you should see:

allow_url_include Off
auto_prepend_file None

2. refresh the page after a couple of seconds. At some point you will see the values changing in the phpinfo() output:

allow_url_include On
auto_prepend_file php://input

Thus it starts showing the POST data prepended to the output.
 [2021-03-19 17:40 UTC] en3py at hotmail dot com
Found the issue and full procedure to reproduce the problem.

We checked this behavior on:
- PHP 7.2.34
- PHP 7.3.26

We were using a Nagios control process to see if the FPM daemon was working, every 15 seconds it made a POST call to the /status entry point of each context.

listen = 0.0.0.0:17302
pm.status_path = /status

1. Service started: the PHP-FPM worker works properly without any issue. POST requests were correctly handled, data was not altered.

2. The Nagios control queried the /status page. This was the response:

[root@mon01 hosts]# /opt/nagios/libexec/check_fpm -p 17302 staging.eu.rightschain.co "/status"
OK: PHP/7.3.26, pool [poolname] active processes 1 idle processes 1 started on 19/Mar/2021:17:31:45 +0000

3. The behavior of the two directives changed (in the phpinfo() output, not the configuration file)

FROM:

allow_url_include Off
auto_prepend_file None

TO:

allow_url_include On
auto_prepend_file php://input

And flapped between the two values resulting in an unstable behavior.

4. Restart the PHP-FPM process, and repeat from step 1. Occurs 100% of the times.

We disabled the /status page and binded the worker to 127.0.0.1 and changed monitoring process. The issue disappeared from all monitored hosts.

For the record, this is the check we were using for the FastCGI gateway:
https://github.com/wuyunfeng/Python-FastCGI-Client

Hope it may be of help for anyone out there.

Cheers
 [2021-03-21 19:42 UTC] bukka@php.net
-Assigned To: +Assigned To: bukka
 [2021-03-21 19:42 UTC] bukka@php.net
> listen = 0.0.0.0:17302

Is this is a publicly accessible server or protect by VPN? Just wondering if something else could hit it with PHP_ADMIN_VALUE. It's definitely not a good idea to open it to the world though. Did you try to use listen.allowed_clients and white list the nagios? Just wondering if it's because of something hits that with PHP_ADMIN_VALUE or there's another issue?
 [2021-03-22 17:56 UTC] en3py at hotmail dot com
The service is binded to 0.0.0.0 but it allows only connections from the monitoring server (firewalled + access list).

The issue happens even if the service is binded on 127.0.0.1 and you make the call from the same server.
 [2021-03-29 16:41 UTC] raqooncoon at gmail dot com
I think this may be about 9000 port of php-fpm service. It must not be available from outside of server, otherwise php-fpm will be vulnerable to sending TCP packets over bogus FastCGI protocol that leads to execution of arbitrary code and changing running php config.
1) Try set
listen = 127.0.0.1:9000
inside www.conf of php-fpm.
2) Make sure that 9000 port is not opened, check ufw settings.
3) If you use docker, DO NOT EXPOSE 9000 port from php-fpm container. Use reverse-proxy nginx and docker network for php-fpm to nginx connection.

Read more about this php-fpm vulnerability https://www.x1a0t.com/2020/02/04/Attack-php-fpm/
 [2021-04-29 09:53 UTC] ahirsch29 at gmail dot com
Same problem with php 8.0.3 - raised the issue here: https://bugs.php.net/bug.php?id=80385
 [2021-04-29 13:34 UTC] nikic@php.net
I've been trying to reproduce this issue based on the instructions from en3py at hotmail dot com, but wasn't able to. I'm not seeing any changes in phpinfo output after querying the FPM status page.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Fri Sep 17 08:03:36 2021 UTC