Nginx of PHP and fastcgi PATH_INFO problem

  • 2020-05-06 12:12:43
  • OfStack

In Apache, AcceptPathInfo is accepted by default for PHP scripts when not configured, that is,

If there is a /laruence/ index.php
in the server
So, for the following request,
 
/laruence/index.php/dummy 
/laruence/dumm 

Apache is accepted as an access to info.php, and PATH_INFO is set to dummy

For Nginx, PATH INFO is not supported, that is, PATH_INFO.
is not set by default
Because the default configuration file support for PHP is very basic, the default configuration for the above access will also be 404
This is deadly for some PHP frameworks that use PATH_INFO to deliver critical information (e.g. Kohana, Thinkphp).

Generally speaking, there are two solutions to this problem. The first is to use rewrite, but the disadvantage of this method is obvious, which is to convert PATH_INFO to Query String. This method is not explained here ~

And the second method is what I'm going to talk about today, simulating PATH_INFO:

First, we know that in Nginx, it is the extension matching of the file name that determines whether or not to be given to the php cgi server for interpretation
 
location ~ .php$ { 
fastcgi_index index.php; 
fastcgi_pass 127.0.0.1:9000; 
include fastcgi_params; 

So, to form such as/laruence/info php/pathinfo such file path, Nginx is not correct to php cgi server. So we need to rewrite this section configured to:
 
location ~ .php {// Fragments matching  
fastcgi_index index.php; 
fastcgi_pass 127.0.0.1:9000; 
include fastcgi_params; 

The script path is now in PHP's hands. How do you increase PATH_INFO?

First, we need to open the cgi.fix_pathinfo configuration item in PHP. After opening this configuration item, PHP will check the access script and PATH_INFO(ini configuration explanation) in SCRIPT_FILENAME according to CGI specification, and modify PATH_INFO(and PATH_TRANSLATED) for the correct value according to SCRIPT_NAME. PHP's initial support for CGI 1.1 was not in place
Then, just add an FASTCGI_PARAM item:
 
location ~ .php { 
fastcgi_index index.php; 
fastcgi_pass 127.0.0.1:9000; 
include fastcgi_params; 
fastcgi_param PATH_INFO $fastcgi_script_name; 

Try it now...

btw: of course, the solution above is to leave the path analysis to PHP, and some friends on the Internet have given another configuration method, which is to analyze the path by Nginx (which does not need fix_pathinfo):
 
location ~ \.php 
{ 
fastcgi_index index.php; 
fastcgi_pass 127.0.0.1:9000; 
include fastcgi_params; 
set $path_info ""; 
set $real_script_name $fastcgi_script_name; 
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { 
set $real_script_name $1; 
set $path_info $2; 
} 
fastcgi_param SCRIPT_FILENAME /var/html/$real_script_name; 
fastcgi_param SCRIPT_NAME $real_script_name; 
fastcgi_param PATH_INFO $path_info; 

Postscript, the recent discovery of a security breach (Nginx + PHP CGI a possible security breach) with this configuration, please be sure to use the second configuration, closed cgi. fix_pathinfo. In addition I personally think about the hole this and Nginx do not have what relation, which does not belong to Nginx holes. Is a configuration problem, now say Nginx Bug everywhere, wrong wrong.

Related articles: