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

PHP 防 SQL 注入終極指南:正確處理 magic_quotes_gpc 與通用過濾函數

     編輯:PHP 綜合知識

SQL 注入曾是 Web 應用頭號殺手,雖然現代框架內建參數化查詢已大幅降低風險,但理解底層防護機制對維護舊專案、排查漏洞仍具關鍵價值。本文深入剖析 magic_quotes_gpc 的行為差異,並提供一個健壯的通用輸入過濾函數,解決「開啟時重複轉義、關閉時裸奔」的兩難困境。

核心問題:magic_quotes_gpc 的雙面性

當 php.ini 中 magic_quotes_gpc = On 時,PHP 自動對 $_GET、$_POST、$_COOKIE 中的單引號(')、雙引號(")、反斜線(\)、NULL 字元加上反斜線轉義。若開發者同時手動調用 addslashes(),將導致雙重轉義,資料庫存入 Tom\'s book,輸出變成 Tom\\'s book,嚴重破壞數據完整性。

反之,若 magic_quotes_gpc = Off 且未手動轉義,單引號直接拼接進 SQL 即構成注入漏洞。

標準解法:運行時檢測與條件轉義

利用 get_magic_quotes_gpc() 動態判斷當前狀態,僅在關閉時補充轉義:

<?php
// 單一變量處理範例
if (!get_magic_quotes_gpc()) {
    $_POST['message'] = addslashes($_POST['message']);
}
// 此時 $_POST['message'] 可安全用於 SQL 拼接(建議仍優先用參數化查詢)
?>

進階方案:遞歸處理多維陣列的通用過濾器

實戰中表單欄位往往成十上百,逐個處理不現實。利用 PHP 超全局變量本質為陣列的特性,封裝遞歸過濾函數:

<?php
function quotes($content) {
    // 僅在 magic_quotes_gpc 關閉時處理
    if (!get_magic_quotes_gpc()) {
        if (is_array($content)) {
            foreach ($content as $key => $value) {
                // 遞歸處理子陣列
                $content[$key] = quotes($value);
            }
        } else {
            // 純量值直接轉義
            $content = addslashes($content);
        }
    }
    // 開啟時直接返回原值,避免雙重轉義
    return $content;
}

// 應用:一鍵淨化所有輸入源
$_GET    = quotes($_GET);
$_POST   = quotes($_POST);
$_COOKIE = quotes($_COOKIE);
$_REQUEST = quotes($_REQUEST);
?>

關鍵優勢

  • 零配置適應:自動適配任意 php.ini 設定,部署無需修改代碼。
  • 深度遞歸:支援多維陣列(如 name="data[key][sub]"),徹底覆蓋複雜表單結構。
  • 性能可控:僅在必要時執行轉義,開啖 magic_quotes_gpc 時近乎零開銷。
  • 易於擴展:可在函數內整合 htmlspecialchars()、trim() 等額外清洗邏輯。

現代最佳實踐提醒

🔴 重要:magic_quotes_gpc 自 PHP 5.4 起已棄用並移除。新專案請直接採用 PDO 預處理語句 或框架 ORM 參數綁定,從根源杜絕注入風險。本文方案僅適用於無法升級的舊系統維護期過渡使用。

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