cgi.fix_pathinfo=1时终极解决Nginx文件类型错误解析漏洞的方法

关于漏洞原理参见 nginx文件类型错误解析漏洞 ,最开始是直接把php.ini中设置 cgi.fix_pathinfo = 0想一劳永逸解决。不过后来发现其导致PHP的超全局变量 $_SERVER['PHP_SELF']为空于是有些程序会出错(比如Discuz会拼接出错误图片头像路径)。于是考虑在保持 cgi.fix_pathinfo =1时如何避免漏洞。

网上搜索到的解决办法挺多比如 再提供一种解决Nginx文件类型错误解析漏洞的方法 ,因为 ifisEvil  加上正则判断存在漏判问题,所以尝试使用其他方式解决。

经过试验找到一个终极解决办法,用try_files替代if判断文件

try_files $fastcgi_script_name =404;

 debug日志中会有类似判断

*308 trying to use file: "/robots.txt/a.php" "/var/htdoc/mychery.net/robots.txt/a.php"

之前在网上搜索到一个办法,经过测试是无效的

try_files $request_filename =404;  #无效的用法!

debug日志如下,判断路径重复拼接是错误的

*339 trying to use file: "/var/htdoc/mychery.net/robots.txt/a.php" "/var/htdoc/mychery.net/var/htdoc/mychery.net/robots.txt/a.php"
 

可以把正确的判断命令加入到fastcgi.conf中:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_paramQUERY_STRING$query_string;

fastcgi_paramREQUEST_METHOD$request_method;

fastcgi_paramCONTENT_TYPE$content_type;

fastcgi_paramCONTENT_LENGTH$content_length;

fastcgi_paramSCRIPT_NAME$fastcgi_script_name;

fastcgi_paramREQUEST_URI$request_uri;

fastcgi_paramDOCUMENT_URI$document_uri;

fastcgi_paramDOCUMENT_ROOT$document_root;

fastcgi_paramSERVER_PROTOCOL$server_protocol;

fastcgi_paramGATEWAY_INTERFACECGI/1.1;

fastcgi_paramSERVER_SOFTWAREnginx/$nginx_version;

fastcgi_paramREMOTE_ADDR$remote_addr;

fastcgi_paramREMOTE_PORT$remote_port;

fastcgi_paramSERVER_ADDR$server_addr;

fastcgi_paramSERVER_PORT$server_port;

fastcgi_paramSERVER_NAME$server_name;

#PHPonly,requiredifPHPwasbuiltwith--enable-force-cgi-redirect

fastcgi_paramREDIRECT_STATUS200;

try_files$fastcgi_script_name=404;

然后在location中引用它:

location ~ \.php$ {

fastcgi_passunix:/tmp/phpfpm/php-fpm.sock;

includefastcgi.conf;

}
 

另外,nginx官方推荐使用try_files替代if相应功能。

相关推荐