nginx 0day exploit for nginx + fastcgi PHP

Jérôme Loyet jerome at loyet.net
Fri May 21 23:45:18 MSD 2010


2010/5/21 Igor Sysoev <igor at sysoev.ru>:
> On Fri, May 21, 2010 at 02:26:31PM -0400, Ian Evans wrote:
>
>> Is this situation only pertaining to sites that allow uploads from forms?
>>
>> Going way back to this thread
>> (http://www.ruby-forum.com/topic/145358#645652) in '08, I needed
>> cgi.fix-pathinfo=1 to fix problems with paths and specific extensionless
>> files I needed run as php.
>>
>> Changing cgi.fix-pathinfo=1 to 0 broke a lot of stuff.
>
> Could you show again how URIs should be mapped to SCRIPT_FILENAME
> and PATH_INFO ? Modern nginx versions support named captures in regex.
>

hi igor,

this a very interesting situation :) And i could be a real security
hole on some configuration.

Let say you have the default configuration (except for the
SCRIPT_FILENAME which has been adapted for my local conf where the
fastcgi server is running on local and uses the same document root as
nginx)

location ~ \.php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $request_filename;
    include        fastcgi_params;
}


Let say the request is
http://mydomain/foo/test.php/virtual/path/to/somewhere.php

the fastcgi request sends the following fastcgi parameters
SCRIPT_FILENAME is set to
/nginx/prefix/html/foo/test.php/virtual/path/to/somewhere.php
PATH_INFO is not set

with fix_pathinfo=1
SCRIPT_FILENAME is transformed to /nginx/prefix/html/foo/test.php
PATH_INFO is set to /virtual/path/to/somewhere.php
in this case, PHP could parse and execute an unwanted file and a
security hole can exists.

with fix_pathinfo=1
SCRIPT_FILENAME is not changed and still
/nginx/prefix/html/foo/test.php/virtual/path/to/somewhere.php
PATH_INFO is not changed and remains unset
in this case, PHP tries to execute the file which really corresponds
to the request which will certenely not exist.

In both case, if the (updated) SCRIPT_FILENAME corresponds to an
existing file on the filesystem, it's interpreted by PHP.

Is it a PHP bug ? I don't really know. fix_pathinfo is a feature which
could be usefull on some case (otherwise why would have it been done
?).
Is it a nginx bug ? I don't think so. It's how nginx works. The guy
who makes the conf should understand what he's doing. But .. see my
following question

Why nginx forwards the request to the fastcgi server if the
SCRIPT_FILENAME does not exists ?
1- if the fastcgi server is not local, the local machine does not have
the script file on its filesystem --> nginx can't check if the file
exists. It would say NO instead of YES.
2- if the fastcgi server is local but running with a user which
doesn't have rights to search for the script filename --> nginx can't
check if the file exists. It would say NO instead of YES
3- if the fastcgi server is local and have access to the file -->
nginx can return 404 without sending the request to the fastcgi
server. This is usefull in this security case, but it's also a
performance enhancement because the fastcgi server won't deal with non
existing files and 404 will be returned quicker and less resources
will be used

Igor, maybe the default conf file is not that good about PHP through fastcgi.
here is an idea:
--- nginx.conf.orig     2010-05-21 21:31:45.000000000 +0200
+++ nginx.conf  2010-05-21 21:36:00.000000000 +0200
@@ -64,9 +64,12 @@
         #
         #location ~ \.php$ {
         #    root           html;
+        #    if (!-e $request_filename) {
+        #        return 404;
+        #    }
         #    fastcgi_pass   127.0.0.1:9000;
         #    fastcgi_index  index.php;
-        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
+        #    fastcgi_param  SCRIPT_FILENAME  $request_filename;
         #    include        fastcgi_params;
         #}


or maybe just add a BIG warning to disable fix.path_info and use
fastcgi_split_path_info to deals with those kind of URL

On my side, I'll check if the fix_pathinfo is really usefull on
php-fpm. If not, I'll try to remove it.

hope this help!

++ Jerome



More information about the nginx mailing list