php cgi.fix pathinfo,Nginx + PHP CGI的安全漏洞:fix_pathinfo

如果你正在使用nginx+php,请关注。

表像:

具体的重现过程,用php代码修改后缀名后上传,比如说www.xxx.com/1.jpg,访问的时候用www.xxx.com/1.jpg/xxx.php 这段jpg代码将会被执行!!!

http://docs.php.net/manual/zh/ini.core.php

cgi.fix_pathinfo “1″ PHP_INI_ALL 从 PHP 4.3.0 起可用 请注意:默认为1

为什么会这样呢?

比如, 如下的nginx conf: location ~ \.php($|/) {

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

set $script $uri;

set $path_info "";

if ($uri ~ "^(.+\.php)(/.*)") {

set $script $1;

set $path_info $2;

}

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$script;

fastcgi_param SCRIPT_NAME $script;

fastcgi_param PATH_INFO $path_info;

}

通过正则匹配以后, SCRIPT_NAME会被设置为”fake.jpg/foo.php”, 继而构造成SCRIPT_FILENAME传递个PHP CGI, 但是PHP又为什么会接受这样的参数, 并且把a.jpg解析呢?

这就要说到PHP的cgi SAPI中的参数, fix_pathinfo了: ; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's

; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok

; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting

; this to 1 will cause PHP CGI to fix it's paths to conform to the spec. A setting

; of zero causes PHP to behave as before. Default is 1. You should fix your scripts

; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.

cgi.fix_pathinfo=1

如果开启了这个选项, 那么就会触发在PHP中的如下逻辑: if (script_path_translated &&

(script_path_translated_len = strlen(script_path_translated)) > 0 &&

(script_path_translated[script_path_translated_len-1] == '/' ||

....//以下省略.

到这里, PHP会认为SCRIPT_FILENAME是fake.jpg, 而foo.php是PATH_INFO, 然后PHP就把fake.jpg当作一个PHP文件来解释执行… So…

解决办法:

1.修改php.ini中的cgi.cgi.fix_pathinfo为0(即使你在php.ini中没有搜到,也要设置,没有搜到表示默认为1)

2.判断文件上传类型时使用严格的判断,至于怎么判断,参见:http://www.54chen.com/php-tech/php-upload-file-types-to-determine-the-complete-program-and-php-nginx-upload-size-and-complete-control-program.html

3.把nginx的判断正则修改为去除/

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

return 403;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值