使用有什么优势吗:
location ~ \.php {
location ~ \..*/.*\.php$ {
return 403;
}
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_intercept_errors on;
}
相比
location ~ \..*/.*\.php$ {
return 403;
}
location ~ \.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_intercept_errors on;
}
我想避免如下所示的任意代码执行:https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#passing-uncontrolled-requests-to-php
在我的简单浏览器测试中,两种方式domain/somedir/file.jpg/1.php
均返回403
,但我仍然不确定这是否就是我需要的全部安全性。此外,“性能”方面是否存在任何差异。
答案1
我个人并不喜欢您所概述的方法,因为如果 .php 文件的实际 URL 中有一个点,您最终可能会得到误报。
一般来说,有三种方法可以避免指示 nginx 执行任意文件。我按照我喜欢的顺序列出了它们。
#1 是将 PHP 配置cgi.fix_pathinfo
为 0。这将确保即使有人传递了 URL,/uploads/avatar32.jpg/index.php
PHP 也会查找该文件,而不是尝试“修复”路径并执行/uploads/avatar32.jpg
。如果未找到完整文件路径,它将返回错误“未指定输入文件”或“主脚本未知”,具体取决于您的 PHP 版本。
#2 是让 nginx 测试是否存在实际文件,如果未找到则返回 404。但是,如果您使用 nginx 作为 PHP 服务器的反向代理/负载平衡器,则此方法不起作用。您的 PHP 位置最终将如下所示:
location ~* \.php$ {
try_files $uri =404;
fastcgi_pass backend;
}
第三个方法是黑名单方法,它利用了只有当攻击者可以将文件上传到您的服务器时此漏洞才会起作用这一事实。因此,例如,如果您的用户上传到 /uploads/,那么您将有一个专门用于此的位置。
location /uploads {
location ~ \.php$ {return 403;}
}