跳轉到內容

PHP 程式設計/配置:Register Globals

來自華夏公益教科書

什麼是 Register Globals?

[編輯 | 編輯原始碼]

PHP 中一個常見的安全問題是 PHP 配置檔案 (php.ini) 中的 register_globals 設定。此設定(可以是 **On** 或 **Off**)指示是否將 EGPCS(環境、GET、POST、Cookie、伺服器)變數的內容註冊為全域性變數。例如,如果 register_globals 為 **On**,則 url http://www.example.com/test.php?id=3 將宣告 $id 為一個 全域性變數,無需任何程式碼。類似地,$DOCUMENT_ROOT 也將被定義,因為它屬於 $_SERVER “超級全域性” 陣列。這兩個例子相當於在指令碼開頭放置以下程式碼

$id = $_GET['id'];
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];

此功能是一個很大的安全風險,您應該確保所有指令碼的 register_globals 都為 **Off**(從 PHP 4.2.0 開始,這是預設設定,從 5.4.0 開始,該設定已完全刪除)。最好透過 PHP 預定義變數來完成,例如超級全域性 $_REQUEST。更安全的做法是使用:$_ENV、$_GET、$_POST、$_COOKIE 或 $_SERVER,而不是使用更通用的超級全域性 $_REQUEST。

假設這段 PHP 程式碼位於表單的接收端。使用者剛剛輸入了錯誤的密碼。$_POST 陣列變數處理它。程式碼將描述如果密碼正確(“正確密碼”假設為“12345”),變數 $admin 將被設定為 TRUE。網站配置表示,如果 $admin 設定為 TRUE,該使用者將擁有管理員許可權。此程式碼與 PHP5 相容。

if (isset($_POST['password']) && $_POST['password'] == "12345") {
    $admin = TRUE;
}

register_globals 不會區分 $_POST 變數和 $_GET 變數。因此,假設使用者輸入了表單並將其帶到了上面的頁面。使用者可能會認為自己應該擁有管理員許可權,即使他們不知道密碼。因此,該使用者可以在該頁面的 URL 後面附加 ?admin=1。當 register_globals 為 **On** 時,這將強制建立變數 $admin 並自動將其值設定為 1,使其等效於 TRUE。因此,register_globals 為 **On** 允許使用者將變數和值**注入**到程式中!這裡,無論使用者是否輸入了正確的密碼,他們現在都可以透過對 URL 做一些操作來獲得管理員許可權。

如您所見,這種情況可能會在任何時候發生,只要有人足夠思考以弄清楚頁面的編碼方式。它可能會發生在許多其他情況下。

另一個例子是會話。當 register_globals = on 時,我們也可以在下面的例子中使用 $username,但同樣,您必須意識到 $username 也可以來自其他方式,比如 GET(透過 URL)。

 // We wouldn't know where $username came from but do know $_SESSION is
 // for session data
 if (isset($_SESSION['username'])) {
     echo "Hello <b>{$_SESSION['username']}</b>";
 } else {
     echo "Hello <b>Guest</b><br />";
     echo "Would you like to login?";
 }

最佳實踐

[編輯 | 編輯原始碼]

避免它的最佳方法是確保在您的 php.ini 中將 register_globals 設定為 **Off**。但作為一個通用的編碼建議,始終初始化您的變數。以下程式碼對之前的程式碼示例進行了小小的補充,但首先將 $admin 設定為 FALSE,因此使用者只能透過條件語句獲得管理員許可權

 $admin = FALSE;
 if (isset($_POST["password"]) && $_POST["password"] == "12345") {
     $admin = TRUE;
 }

filter_input()

[編輯 | 編輯原始碼]

由於超級全域性陣列訪問容易受到 程式碼注入[1] 的攻擊,出於安全原因,最好使用 filter_input()[2] 的語法

<?php
echo filter_input(INPUT_GET, 'password'); // good
echo $_GET['password'];                   // not good
?>

參考資料

[編輯 | 編輯原始碼]

更多資訊

[編輯 | 編輯原始碼]


華夏公益教科書