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

PHP 防禦 SQL 注入攻擊(三):預處理語句與最佳實踐

     編輯:PHP 綜合知識

前言

延續前兩篇關於 SQL 注入攻擊的討論,本文將深入探討如何從根本上解決資料庫輸入安全問題。前文提到資料庫自帶的字符串過濾功能(如 mysql_real_escape_string)並非所有資料庫都支援,且 Base64 編碼雖能繞過特殊字符,但會增加 33% 儲存空間,且導致 PostgreSQL 無法使用 LIKE 查詢。顯然,單靠資料庫層面的轉義並不足夠。

核心解決方案:預處理語句

預處理語句是目前公認最有效的防禦手段。其原理是將 SQL 查詢的結構與數據分離:先定義查詢模板(含佔位符),再綁定參數執行。資料庫引擎會預先編譯 SQL 結構,執行時僅填入數據,徹底杜絕了注入可能。

PostgreSQL 範例

// 1. 定義預處理語句,指定參數類型為 text
pg_query($conn, "PREPARE stmt_name (text) AS SELECT * FROM users WHERE name=$1");

// 2. 執行並傳入實際參數
pg_query($conn, "EXECUTE stmt_name ({$name})");

// 3. 釋放預處理語句資源
pg_query($conn, "DEALLOCATE stmt_name");

上例中,$1 為佔位符,除此以外的所有字符均為固定結構,不可更改。這種「模板+參數」模式確保了用戶輸入永遠不會被解釋為 SQL 指令。

為何預處理語句更優越?

  • 徹底隔離代碼與數據:SQL 邏輯在編譯階段確定,運行時數據僅作為字面值處理。
  • 效能提升:重複執行同結構查詢時,資料庫可複用執行計劃。
  • 跨資料庫支援:MySQL、PostgreSQL、SQLite、Oracle、SQL Server 等主流資料庫均支援(語法略有差異)。

PHP 中的實踐建議

在 PHP 中,推薦使用 PDO 或 mysqli 的預處理介面,而非舊式 mysql_* 函數。例如:

$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute(['name' => $name]);
$result = $stmt->fetchAll();

總結

雖然早期 PHP 開發者常依賴 magic_quotes_gpc、addslashes 或資料庫專用轉義函數,但這些方法皆存在覆蓋面不全、重複轉義、編碼問題等缺陷。預處理語句從架構層面解決了 SQL 注入,應作為現代 PHP 開發的標準配置。下一篇將探討更多進階防禦技巧與實戰案例。

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