關於漏洞原理參見 nginx文件類型錯誤解析漏洞 ,最開始是直接把php.ini中設置 cgi.fix_pathinfo = 0想一勞永逸解決。不事後來發現其致使PHP的超全局變量 $_SERVER['PHP_SELF']爲空因而有些程序會出錯(好比Discuz會拼接出錯誤圖片頭像路徑)。因而考慮在保持 cgi.fix_pathinfo =1時如何避免漏洞。php
網上搜索到的解決辦法挺多好比 再提供一種解決Nginx文件類型錯誤解析漏洞的方法 ,由於 ifisEvil 加上正則判斷存在漏判問題,因此嘗試使用其餘方式解決。 html
通過試驗找到一個終極解決辦法,用try_files替代if判斷文件nginx
try_files $fastcgi_script_name =404;
debug日誌中會有相似判斷 shell
*308 trying to use file: "/robots.txt/a.php" "/var/htdoc/mychery.net/robots.txt/a.php"
以前在網上搜索到一個辦法,通過測試是無效的php-fpm
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_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_NAME $fastcgi_script_name; 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 GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; 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; try_files $fastcgi_script_name =404;
而後在location中引用它:ui
location ~ \.php$ { fastcgi_pass unix:/tmp/phpfpm/php-fpm.sock; include fastcgi.conf; }
另外,nginx官方推薦使用try_files替代if相應功能。.net