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-11-26 23:59 UTC
Votes:29
Avg. Score:4.6 ± 0.8
Reproduced:26 of 26 (100.0%)
Same Version:7 (26.9%)
Same OS:5 (19.2%)
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
Have you experienced this issue?
Rate the importance of this bug to you:

 [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.
 [2021-11-21 16:03 UTC] blissweb at hotmail dot com
We have this issue.  Our FPM port is set to 9001, so its not related to 9000.   Centos 7.4.25 php-fpm  7.9 centos.  As others have said, the auto_prepend_file starts getting set on its own.
 [2021-11-22 21:16 UTC] dklugmann2 at yahoo dot com
We also have this problem on Centos 7.

I have tried setting the auto_prepend_file to blank in all the possible config files but it doesn't help. The issue comes back in a number of hours

Just to stress this is a major bug and makes running our website through docker very difficult if not impossible as all kinds of parameters are displayed to the user. A pity as Docker is in many ways an excellent product.

I hope someone in the team can take a look at the issue as it has been a year now since the first comments above.

Our only solution for now is to bounce the container every few hours which is not ideal.

Thanks
 [2021-11-22 21:42 UTC] requinix@php.net
Does anyone replying to this NOT have their port 9000 open to the internet and ripe for abuse? Even if you're sure you do not, use an online port checker to verify it.
 [2021-11-23 12:54 UTC] bukka@php.net
Is anyone able to provide reproducible steps that can lead to this problem in recreatable environment?

If it's too difficult it could also help to use to analyze the traffic going to the instance (e.g. using tcpdump or similar) and possibly checking if PHP_ADMIN_VALUE with auto_prepend_file can be seen there.

In general as much as details about your environemnt setup would be helpful for futher investigation.

Potentially I could also prepare a quick patch that will disable PHP_ADMIN_VALUE setting through fcgi but would require someone who is experiencing the issue and is willing to compile and deploy patched php-fpm to the server...
 [2021-11-23 12:56 UTC] bukka@php.net
I meant as much details as possible about the environment will be helpful too.
 [2021-11-23 14:38 UTC] dklugmann2 at yahoo dot com
Hi Bukka

Thanks for responding. We would be very happy to work with you to get to the bottom of this issue.

We can send you the details to recreate the issue or alternatively what may be faster since it is basically a new virtually empty VPS machine we could supply an example phpinfo page showing the issue of the auto_prepend getting set periodically and we could provide you access details for our machine also for any debugging you may want to try.

Please let us know what would be best for you.

Also our port 9000 is closed i just checked.

Thanks

David
 [2021-11-23 21:34 UTC] bukka@php.net
Hi David,

It sounds good to me. If you could email me details how to recreate first, that would be awesome. Ideally I would like to be able to recreate the issue locally on my computer because my setup will make it easier for me to debug it. But if I'm not successful locally, then getting access to the machine would be definitely useful. Mainly I would be then interested what is happening exactly at time of the INI changes (e.g. having captured traffic of the port 9000 could be quite useful) because after it changes, it's most likely too lite to see anything so in any case the steps to recreate are very important.

Thanks

Jakub
 [2021-11-23 23:37 UTC] dklugmann2 at yahoo dot com
Hi Jakub

I have emailed you our setup.

Many thanks for looking at this issue.

David
 [2021-11-26 14:09 UTC] dklugmann2 at yahoo dot com
Just a comment from our issue

This does appear to be 100% a hack attack exposing a php-fpm vulnerability

We updated the port in the php-fpm part of our yml docker file definition to be preceded with a 127.0.0.1 in front of the port name in the ports section thus restricting it to localhost access only.

We also added a firewall with firewallcmd and limited access to only the very essential ports.

After that the issue has not reappeared.

Thanks

David
 [2021-11-26 23:59 UTC] bukka@php.net
Just to repeat what was said before. This is not a vulnarebality but a feature that has been present in PHP-FPM for some time. Personally I think it's not a really good thing to allow web servers to change PHP ini through the FastCGI env variables and I plan to introduce an option to disable it. But again it is on purpose and it is not a bug. There might be web server configs relaying on it so we can't break it in minore release so the option would be an optional feature that you will need to configure. We could maybe disable it by default in PHP 9.

Also I see in some comments confusion about the ports. It doesn't really matter what port number PHP-FPM listen on. What matters is that this port is protected against external traffic (e.g. by configuring firewall) and not exposed to anything else than your web server.

Please also note that even if we disable PHP_VALUE and PHP_ADMIN_VALUE, it's still not good idea to allow external traffic to PHP-FPM. It wasn't designed for that and we would need to do some additional review and hardening to be sure it's safe.
 [2022-01-22 03:53 UTC] mr dot liuyuwen at gmail dot com
When i turn off expose php-fpm port to internet, this bug gone.

so i think this bug product when you open the fpm port ,and you meet fastcgi attack. i will fake a cgi request ,and then change you php.ini config. i will set auto_prepend_file = php://input.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Thu May 19 02:05:44 2022 UTC