According to this post, it was said that if I am using PHP/Nginx, for better security, I should either

cgi.fix_pathinfo = 0


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

In other tutorial it recommend the style of

fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;

Are they contradictive to each others? Any security recommendation?


3 Answers 3


You're referring to an issue where an attacker can upload arbitrary code to an nginx web server and then trick the server into executing it as PHP. (No CVE exists for this issue as it is technically a misconfiguration rather than a vulnerability.)

Any of the methods you listed can be used to remediate the issue.

Another, simpler way of remediating this issue is to add the following into your PHP location:

try_files $uri =404;

Though this only works if nginx and PHP are running on the same server, which is almost always true.

The recommendation, of course, is that you clearly document what you're doing and why.

  • this only works if you're not using fastcgi_split_path_info, as fastcgi_split_path_info expects the uri not to end with .php, whereas try_files $fastcgi_script_name =404; works with fastcgi_split_path_info whether the uri has matched the regex, in which case takes the first match occurrence as it's value or failed to match
    – Andy
    Commented Oct 28, 2019 at 18:21

In recent versions of php, this is no longer an issue:

From the file /etc/php-fpm.d/www.conf:

; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5

On Ubuntu 16.04 LTS Server, after installing nginx using the package manager, the example PHP location in /etc/nginx/sites-available/default includes snippets/fastcgi-php.conf. This is the contents of that file:

# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;

# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;

# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

fastcgi_index index.php;
include fastcgi.conf;

It appears that the problem is mitigated by using fastcgi_split_path_info to get $fastcgi_script_name and $fastcgi_path_info. Then try_files is used to look for $fastcgi_script_name. If the PHP file does not exist, a 404 Not Found is returned.

I would be curious to know if this solution is implemented by other distributions.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .