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

PHP 防止 SQL 注入的函數詳解與最佳實踐

     編輯:PHP 相關知識

前言

SQL 注入是 Web 應用中最常見也最危險的安全漏洞之一。PHP 提供了多種函數來轉義輸入數據,但並非所有函數都同樣可靠。本文將深入分析 addslashes、mysql_real_escape_string、mysql_escape_string 的區別,並給出現代 PHP 開發中推薦的防注入方案。

1. addslashes() 的局限性

早期許多 PHP 程式碼依賴 addslashes() 來防止 SQL 注入。然而,這個函數僅針對單字節字符串有效,在多字節編碼(如 GBK、Big5)環境下存在繞過風險。

繞過原理: 攻擊者可使用 0xbf27 代替單引號(0x27)。addslashes() 會將其轉為 0xbf5c27,但數據庫在解析多字節字符時,0xbf5c 會被視為一個合法字符,導致後面的單引號「倖存」,從而構成注入。

結論: addslashes() 只適合單字節字符集(如 Latin1),不建議 用於中文等多字節環境。

2. mysql_real_escape_string() —— 推薦的轉義函數

mysql_real_escape_string(string $unescaped_string, resource $link_identifier = null) 會根據當前連接的字符集正確轉義特殊字符,是防注入的標準選擇。

  • 自動處理字符集,支援多字節編碼。
  • 需在已建立 MySQL 連接後調用。
  • 注意: 不轉義 % 和 _(LIKE 查詢通配符),如需防禦需額外處理。

範例代碼

<?php
$item = "Zak's and Derick's Laptop";
$escaped_item = mysql_real_escape_string($item);
printf("Escaped string: %s\n", $escaped_item);
// 輸出: Escaped string: Zak\'s and Derick\'s Laptop
?>

3. mysql_escape_string() —— 已棄用的替代品

功能與 mysql_real_escape_string() 類似,但不接受連接資源,也不考慮當前字符集。PHP 4.3.0 之前版本只能用此函數,現已棄用,請勿在新項目中使用。

4. 綜合處理策略:兼容 magic_quotes_gpc

舊版 PHP 可能開啟 magic_quotes_gpc 自動轉義 GET/POST/COOKIE 數據。為避免雙重轉義,建議採用如下封裝函數:

function clean_input($dirty) {
    if (get_magic_quotes_gpc()) {
        $clean = mysql_real_escape_string(stripslashes($dirty));
    } else {
        $clean = mysql_real_escape_string($dirty);
    }
    return $clean;
}

5. 現代最佳實踐:預處理語句

自 PHP 5.1 起,PDO 和 mysqli 都支援預處理語句,這是防止 SQL 注入的根本解決方案。參數化查詢將數據與 SQL 邏輯徹底分離,無需手動轉義。

// PDO 範例
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :name');
$stmt->execute([':name' => $username]);
$row = $stmt->fetch();

總結對比表

函數字符集感知PHP 版本要求推薦程度
addslashes()否所有版本❌ 不推薦
mysql_escape_string()否PHP 4.3.0 前❌ 已棄用
mysql_real_escape_string()是PHP 4.3.0+⚠️ 僅限舊項目維護
PDO / mysqli 預處理是PHP 5.1+✅ 強烈推薦

在新專案中,請直接使用 PDO 或 mysqli 的預處理語句;維護老代碼時,務必用 mysql_real_escape_string() 並注意字符集設置。

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