nginx 0day exploit for nginx + fastcgi PHP

Jérôme Loyet jerome at loyet.net
Mon May 24 10:56:37 MSD 2010


2010/5/24 Weibin Yao <nbubingo at gmail.com>:
> Jérôme Loyet at 2010-5-22 3:45 wrote:
>>
>> 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
>>
>
> I think we should use the directive of fastcgi_split_path_info and add
> PATH_INFO by nginx itself.
>>
>> On my side, I'll check if the fix_pathinfo is really usefull on
>> php-fpm. If not, I'll try to remove it.
>>
>
> The php developer said this feature is very useful in the mod_rewrite with
> the PATH_INFO parameter.

do you have any links to discution about this ? or concrete examples ?

thx

>>
>> hope this help!
>>
>> ++ Jerome
>>
>> _______________________________________________
>> nginx mailing list
>> nginx at nginx.org
>> http://nginx.org/mailman/listinfo/nginx
>>
>>
>
>
> --
> Weibin Yao
>
>
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://nginx.org/mailman/listinfo/nginx
>



More information about the nginx mailing list