首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

深入解析 PHP register_globals:安全風險與解決方案全攻略

     編輯:PHP 綜合知識

什麼是 register_globals?

register_globals 是 PHP 配置指令,控制外部變量(如 $_GET、$_POST、$_COOKIE 等)是否自動註冊為全局變量。自 PHP 4.2.0 起,預設值改為 Off,這是為了提升安全性。

為什麼要強制關閉?

當 register_globals = On 時,用戶提交的表單數據、URL 參數、Cookie 等會直接變成全局變量(如 $username、$password),無需通過超全局數組獲取。這極易導致安全漏洞:攻擊者可通過構造參數覆蓋內部變量,繞過權限檢查。

經典漏洞示例

<?php
// 危險代碼:未初始化 $authorized 直接判斷
if ($username == 'admin' && $password == 'secret') {
    $authorized = true;
}
if (!$authorized) {
    // 顯示登錄表單
} else {
    // 顯示機密內容
}
?>

攻擊者只需訪問 ?authorized=1 即可繞過驗證,因為 $authorized 被自動註冊為全局變量並賦值 1。

DedeCMS 強制關閉的應對方案

DedeCMS 在 include/common.inc.php 中強制要求 register_globals = Off。若您的空間不支持修改 php.ini,可嘗試以下方法:

方案一:修改 php.ini(獨立服務器)

register_globals = Off

修改後重啟 Apache 生效。

方案二:.htaccess 文件(虛擬主機)

在網站根目錄創建或編輯 .htaccess,添加:

php_flag register_globals off

方案三:ini_set() 函數(部分環境有效)

ini_set('register_globals', '0');

放在入口文件最開頭。

方案四:刪除 DedeCMS 檢查代碼(不推薦)

編輯 include/common.inc.php,刪除或註釋以下代碼:

if(ini_get('register_globals')){
    exit('<a href="https://docs.dedecms.com/doku.php?id=register_globals">php.ini register_globals must is Off! </a>');
}

警告:這會降低系統安全性,僅作為臨時應急。

register_globals = Off 時的正確變量獲取方式

表單 Method獲取方式
GET$_GET['user_name']
POST$_POST['user_name']

切勿直接使用 $user_name,必須顯式從超全局數組取值。

register_globals = Off 導致網站打不開的解決方法

部分舊項目依賴 On 風格編寫,升級後出現「Undefined index/variable」錯誤。可在公共配置文件(如 config.inc.php)中加入兼容代碼模擬 On 行為:

<?php
if (!ini_get("register_globals")) {
    extract($_POST);
    extract($_GET);
    extract($_SERVER);
    extract($_FILES);
    extract($_ENV);
    extract($_COOKIE);
    if (isset($_SESSION)) {
        extract($_SESSION);
    }
}
?>

注意:此代碼僅緩解兼容性問題,不保證 100% 可用,且會重新引入安全風險,建議逐步重構代碼改用超全局數組。

「Undefined index」與「Undefined variable」錯誤的徹底解決

錯誤原因

直接使用未定義的數組鍵或變量,如 $act = $_POST['act']; 當 act 不存在時觸發 Notice。

解決方案對比

  1. 修改 php.ini 錯誤報告級別(治標)
    error_reporting = E_ALL & ~E_NOTICE
    
    或運行時代碼:ini_set("error_reporting", "E_ALL & ~E_NOTICE");
  2. 關閉錯誤顯示(生產環境推薦)
    display_errors = Off
    
  3. 代碼層面規範寫法(治本,強烈推薦)
    • 使用 isset() 或 empty() 判斷:$act = isset($_POST['act']) ? $_POST['act'] : '';
    • 封裝獲取函數:
      function _get($key) {
          return isset($_GET[$key]) ? $_GET[$key] : null;
      }
      function _post($key) {
          return isset($_POST[$key]) ? $_POST[$key] : null;
      }
      
    • PHP 7+ 可用空合併運算符:$act = $_POST['act'] ?? '';

最佳實踐總結

  • 始終保持 register_globals = Off。
  • 嚴格使用 $_GET、$_POST、$_REQUEST 等超全局數組獲取外部輸入。
  • 所有變量使用前先初始化或判斷存在性。
  • 生產環境關閉 display_errors,記錄錯誤日誌而非直接輸出。
  • 定期進行代碼安全審計,清理舊式寫法。

掌握 register_globals 的機制與風險,是寫出安全 PHP 代碼的基礎功課。從今天起,堅持「Off 風格」編程,為項目築起第一道防線。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved