5

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

cgi.fix_pathinfo = 0

or

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?

Thanks.

Richard Hansen
  • 3,870
  • 1
  • 19
  • 17
Howard
  • 2,135
  • 13
  • 48
  • 72

3 Answers3

4

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.

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • 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 Oct 28 '19 at 18:21
2

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
0

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.

David Cullen
  • 101
  • 4