首先我们要知道
1.request_filename表示当前连接请求的文件路径,由root或alias指令与URI请求生成。这个变量是本地文件系统的文件名称
2.!-e判断不存在
3.set在这里是设定shell变量并赋值
4.剩余的就是if判断,~*区分大小写,\转义字符,其余的这里不多说了
下面来对比下张宴给出的php_info的俩个解决方案
if ($request_filename ~* .*\.(php|php5)$) {
set $is_path_info '0';
}
if (-e $request_filename) {
set $is_path_info '1';
}
if ($is_path_info ~ '0') {
return 403;
}
if ($request_filename ~* (.*)\.php) {
set $php_url $1;
}
if (!-e $php_url.php) {
return 403;
}注意:在nginx.conf里标示代码的红色部分location ~* .*\.php($|/),如不修改会造成php_info伪静态无法使用
明显区别就是判断的第一句最后的$符号,是结尾的意思,也就是说不是php结尾即可- -!!,之后去掉了$只去掉$还不行,
重启nginx会出错[emerg]: invalid condition “.*\.php”需要把.*用括号,括起来
至于为什么michael说如http://localhost/..1.jpg/1.php/?abc=1这样的url可以绕过第一种配置.
原因其实很简单,大家可以新建test.php代码如下
<?system ($_GET[id]);?>访问http://http://localhost/test.php?id=uname%20-a和http://localhost/test.php/?id=uname%20-a
同样是可以执行的,根据以上判断这个大家不难理解,所以什么”..xx.jpg”前面的点有没有都是无所谓的.这个也算是一个bug吧
为了便于多个虚拟主机引用,我们可以加入fcgi.conf,内容如下
if ($request_filename ~* (.*)\.php) {
set $php_url $1;
}
if (!-e $php_url.php) {
return 403;
}
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $uri;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200; |
|