May 26

nginx [engine x] is a HTTP and reverse proxy server, as well as a mail proxy server written by Igor Sysoev. It has been running for more than five years on many heavily loaded Russian sites including. The vulnerability will let error file type as php file. It’s a very critical bug.

Generally, nginx will parse php file by cgi. Example:

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

In location part,nginx will proceed request by URI variable, and the SCRIPT_FILENAME’s value will be defined by $fastcgi_script_name, the $fastcgi_script_name variable default is open by cgi.fix_pathinfo option  in php.ini file.

Assume, have a the url http://www.goitowrld.com/nginx.jpg, you can try to visit fllow url.

http://www.goitworld.com/nginx.jpg/nginx.php

will have a URI /nginx.jpg/nginx.php

By location command,the request will submit to fastcgi proceed,the SCRIPT_FILENAME variable will set to /script/nginx.jpg/nginx.php

while cgi.fix_pathinfo parameter have been set to 1, now it will split SCRIPT_FILENAME and PATH_INFO to

/script/nginx.jpg and nginx.php

Final the nginx.jpg will be parsed as php file.

Brose url http://www.goitowrld.com/nginx.jpg respone

HTTP/1.1 200 OK
Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:05:30 GMT
Content-Type: image/jpeg
Content-Length: 18
Last-Modified: Thu, 20 May 2010 06:26:34 GMT
Connection: keep-alive
Keep-Alive: timeout=20
Accept-Ranges: bytes

Brose url http://www.goitowrld.com/nginx.jpg/nginx.php respone

HTTP/1.1 200 OK
Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:06:49 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
X-Powered-By: PHP/5.2.6

Solution:

1.modify php.ini file and set parameter

cgi.fix_pathinfo=0

2.modify nginx config file

if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}

Related Posts

2 Responses to “nginx php file parse vulnerability”

  1. tuurtnt says:

    Hi,

    if ( $fastcgi_script_name ~ \..*\/.*php ) {
    return 403;
    }

    is a good solution, only problem is that now links like: connector.php?command=Init
    are not working anymore… Got a solution?

  2. tuurtnt says:

    This is the best fix I have seen for this giant security issue:
    (I need to use: cgi.fix_pathinfo=0 btw)

    if ( $fastcgi_script_name ~ \..*\/.*php ) {
    return 403;
    }

    thanks!

Leave a Reply

preload preload preload