1. 程式人生 > >php全域性變數漏洞 $GLOBALS

php全域性變數漏洞 $GLOBALS

在Discuz程式碼中有這麼一段:
if (isset($_REQUEST[‘GLOBALS’]) OR isset($_FILES[‘GLOBALS’])) {
 exit(‘Request tainting attempted.’);
}
register_globals 是php中的一個控制選項,可以設定成off或者on ,預設為off,決定是否將EGPCS(Environment,GET,POST,Cookie,Server)變數註冊為全域性變數。
如果register_globals開啟的話, 客戶端提交的資料中含有GLOBALS變數名, 就會覆蓋伺服器上的$GLOBALS變數.
所以 這段程式碼, 就是判斷, 如果提交的資料中有GLOBALS變數名, 就終止程式。
 
由此引起的安全問題成為PHP的“自動全域性變數漏洞”,所以我們要堅決把register_globals關掉。並且使用$_GET, $_POST, $_COOKIE 而非$_REQUEST 。
Discuz!論壇繞過全域性變數防禦漏洞由於php5.3.x版本php.ini的設定中request_order 預設值為GP ,導致Discuz! 6.x/7.x中可以繞過全域性變數防禦。
 
在include/global.func.php中:
 
function daddslashes($string, $force = 0) {
    !defined(‘MAGIC_QUOTES_GPC’) && define(‘MAGIC_QUOTES_GPC’, get_magic_quotes_gpc());
    if(!MAGIC_QUOTES_GPC || $force) {
        if(is_array($string)) {
            foreach($string as $key => $val) {
                $string[$key] = daddslashes($val, $force);
            }
        } else {
            $string = addslashes($string);
        }
    }
    return $string;
}
 
include/common.inc.php中:
 
foreach(array(‘_COOKIE’, ‘_POST’, ‘_GET’) as $_request) {
    foreach($$_request as $_key => $_value) {
        $_key{0} != ‘_’ && $$_key = daddslashes($_value);
    }
}
 
在register_globals=on時通過提交GLOBALS變數就可以繞過上面的程式碼。為了防範這種情況,Discuz!中有如下程式碼:
 
if (isset($_REQUEST[‘GLOBALS’]) OR isset($_FILES[‘GLOBALS’])) {
    exit(‘Request tainting attempted.’);
}
 
$_REQUEST這個超全域性變數的值受php.ini中request_order的影響,在最新的php5.3.x系列中,request_order預設值為GP,也就是說預設配置下$_REQUEST只包含$_GET和$_POST而不包括$_COOKIE。通過COOKIE就可以提交GLOBALS變數。
 
臨時解決方法:
 
更改php 5.3.x裡的php.ini設定,設定request_order 為GPC 。
 
補充:
string substr ( string string, int start [, int length] )
其中start如果為負,則從字串最後一個字元開始向回倒數到start字元,作為起始點。
如果length為負,則從字串最後一個字元開始向回倒數到length字元,作為終點。
其中,如果字串長度小於或等於start,則返回false。
如果起點位置超過終點位置,則返回一個空字串。
 
set_magic_quotes_runtime(0)
在php.ini的配置檔案中,有個布林值的設定,就是magic_quotes_runtime,當它開啟時,php的大部分函式自動的給從外部引入的(包括資料庫或者檔案)資料中的溢位字元加上反斜線。
當然如果重複給溢位字元加反斜線,那麼字串中就會有多個反斜線,所以這時就要用set_magic_quotes_runtime()與get_magic_quotes_runtime()設定和檢測php.ini檔案中magic_quotes_runtime狀態。
為了使自己的程式不管伺服器是什麼設定都能正常執行。可以在程式開始用get_magic_quotes_runtime檢測設定狀態秋決定是否要手工處理,或者在開始(或不需要自動轉義的時候)用set_magic_quotes_runtime(0)關掉。
magic_quotes_gpc設定是否自動為GPC(get,post,cookie)傳來的資料中的'”加上反斜線。可以用get_magic_quotes_gpc()檢測系統設定。如果沒有開啟這項設定,可以使用addslashes()函式新增,它的功能就是給資料庫查詢語句等的需要在某些字元前加上了反斜線。這些字元是單引號(’)、雙引號(”)、反斜線()與 NUL(NULL 字元)。
 
error_reporting(0)
// Turn off all error reporting
error_reporting(0);
即關閉所有錯誤輸出。