php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74129 Incorrect SCRIPT_NAME with apache ProxyPassMatch when spaces are in path.
Submitted: 2017-02-19 17:10 UTC Modified: -
From: christian at groschupp dot org Assigned:
Status: Closed Package: FPM related
PHP Version: 7.1.2 OS: CentOS 7.3.1611
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: christian at groschupp dot org
New email:
PHP Version: OS:

 

 [2017-02-19 17:10 UTC] christian at groschupp dot org
Description:
------------
php version: 7.1.2
apache version: 2.4.6

apache configuration:
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1


Working apache configuration
<FilesMatch "\.php$">
       SetHandler "proxy:fcgi://localhost:9000"
</FilesMatch>

I need the ProxyPassMatch variant, because i have also a apache 2.2 and php 5.6 setup, where i can't use SetHandler.

Test script:
---------------
# Script to reproduce on CentOS 7

yum install -y epel-release
rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install -y httpd php71-php-fpm

cat << EOF > /var/www/html/index.php
<?php
echo 'Value: ' . \$_SERVER['SCRIPT_NAME'] . '<br>';
echo 'Expected Value: ' . '/index.php'
?>
EOF

scl enable php71 php-fpm

echo "ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1" >> /etc/httpd/conf.d/welcome.conf

apachectl -D FOREGROUND

Expected result:
----------------
When requesting "/index.php/1 2 3"

$_SERVER["SCRIPT_NAME"]: "/index.php"

Actual result:
--------------
$_SERVER["SCRIPT_NAME"]: "/index.php/1 2 3"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-08-08 21:07 UTC] rainer dot jung at kippdata dot de
Adding some partial problem info: I expect the problem to be in the following lines in fpm/fpm_main.c:

1234                                 } else if (apache_was_here && env_script_name) {
1235                                     /* Using mod_proxy_fcgi and ProxyPass, apache cannot set PATH_INFO
1236                                      * As we can extract PATH_INFO from PATH_TRANSLATED
1237                                      * it is probably also in SCRIPT_NAME and need to be removed
1238                                      */
1239                                     int snlen = strlen(env_script_name);
1240                                     if (snlen>slen && !strcmp(env_script_name+snlen-slen, path_info)) {
1241                                         FCGI_PUTENV(request, "ORIG_SCRIPT_NAME", orig_script_name);
1242                                         env_script_name[snlen-slen] = 0;
1243 SG(request_info).request_uri = FCGI_PUTENV(request, "SCRIPT_NAME", env_script_name);
1244                                     }
1245                                 }
1246                                 env_path_info = FCGI_PUTENV(request, "PATH_INFO", path_info); 

Here SCRIPT_NAME gets compared to PATH_INFO in the strcmp() call. Now when using mod_proxy_fcgi Apache sends SCRIPT_NAME non-percent-encoded as required by the CGI spec. But PATH_INFO is extracted from SCRIPT_FILENAME which is percent-encoded. That means all is fine as long as the PATH_INFO part does not contain anything that gets encoded. As soon as chars which need encoding are contained, the strcmp() fails and SCRIPT_NAME will not get adjusted.

Furthermore, even if SCRIPT_NAME would be encoded, it would still be important, that the percent-encoding of SCRIPT_FILENAME and SCRIPT_NAME use the same character case for the hex digits, eg. not mixing %5B and %5b.

As a workaround I adjusted SCRIPT_NAME in mod_proxy_fcgi to be consistent with SCRIPT_FILENAME even though that's not CGI-spec compliant using the following directive:

ProxyFCGISetEnvIf "reqenv('SCRIPT_FILENAME') =~ m|.*${APP_DIR}(/.*)|" SCRIPT_NAME "$1"

Here APP_DIR is a Unix env var or Define'd var containing the path to the PHP application (could be your DocumentRoot). One can also use the verbatim path there instead of a variable.

the correct fix would probably be to use a percent-decoded path_info in the strcmp() inside fpm_main.c.
 [2020-07-15 17:54 UTC] rainer dot jung at kippdata dot de
This problem is still existing in the current 7.4.8.
 [2023-03-19 13:18 UTC] git@php.net
Automatic comment on behalf of bukka
Revision: https://github.com/php/php-src/commit/0d4d471847902dcb44d047d3bbf3f25f9aacdf88
Log: Fix bug #74129: Incorrect SCRIPT_NAME with apache ProxyPassMatch
 [2023-03-19 13:18 UTC] git@php.net
-Status: Open +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC