php cgi漏洞,Nginx + PHP CGI的一个可能的安全漏洞
現在普遍的Nginx + PHP cgi的做法是在配置文件中, 通過正則匹配Nginx(PHP/fastcgi的PATH_INFO問題,設置SCRIPT_FILENAME, 今天發現了一個這種方式的安全漏洞.
為什么會這樣呢?
比如, 如下的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 the file doesn't exist, try to extract PATH_INFO out
of it by stat'ing back through the '/'
this fixes url's like /info.php/test
*/
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…
這個隱患的危害用小頓的話來說, 是巨大的.
對于一些論壇來說, 如果上傳一個圖片(實際上是惡意的PHP腳本), 繼而構造這樣的訪問請求…
所以, 大家如果有用這種服務器搭配的, 請排查, 如果有隱患,
請關閉fix_pathinfo(默認是開啟的).
cgi.fix_pathinfo=0
總結
以上是生活随笔為你收集整理的php cgi漏洞,Nginx + PHP CGI的一个可能的安全漏洞的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android日志[基础篇]二 Andr
- 下一篇: MySQL 优化 —— WHERE 子句