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

PHP addslashes() 與 SQL 注入防護:為什麼它不夠用?正確防禦方案

     編輯:PHP 相關知識

addslashes() 做了什麼?

<?php
$str = "O'Reilly";
echo addslashes($str); // O\'Reilly

// 轉義字符: ' (單引號)  " (雙引號)  \ (反斜槿)  NULL 字節

它僅做字符級轉義,不理解 SQL 語法上下文,不處理編碼、佔位符、多字節字符繞過 (GBK 编码注入) 等問題。

為什麼不夠用?

  1. 編碼繞過:GBK/Big5 多字節編碼中,0xbf27 組合可繞過單引號轉義 (經典 %bf%27 攻擊)。
  2. 上下文盲區:數值型字段、LIKE 通配符 (% _)、表名/列名、ORDER BY 子句等無法用引號包裹,addslashes 無效。
  3. 二次注入:轉義後存入數據庫,後續查詢未轉義直接拼接,導致注入。
  4. 不支援預處理:現代防注入核心是參數化查詢 (Prepared Statements),addslashes 屬於拼接 SQL 範式,根本機制不同。

正確防禦體系

1. 核心:PDO / MySQLi 預處理語句

<?php
// PDO (推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false, // 關鍵:使用真正預處理
]);

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->execute([$email, 1]);
$user = $stmt->fetch();

// MySQLi
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$stmt->execute();

原理:SQL 模板與數據分離發送給數據庫服務器,服務器解析模板生成執行計劃,再綁定參數執行,參數永遠不會被解析為 SQL 代碼。

2. 輔助:輸出編碼 (防 XSS,非 SQL 注入)

<?php
// HTML 上下文
echo htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

// JavaScript 上下文
echo json_encode($str); // 自動處理引號、換行、Unicode

// Shell 命令上下文
$escaped = escapeshellarg($userInput);

3. 避免動態表名/列名拼接

若必須動態,嚴格白名單驗證:

$allowedTables = ['users', 'orders', 'logs'];
$table = in_array($inputTable, $allowedTables) ? $inputTable : 'users';
$sql = "SELECT * FROM `$table` WHERE ..."; // 反引號包裹標識符

addslashes() 仍有用武之地

  • 老舊項目無法引入 PDO/MySQLi 時的臨時緩解 (需配合 mysql_real_escape_string() 並設置連接字符集)。
  • 生成 SQL 腳本文件、導出 INSERT 語句等離線場景。
  • 非數據庫字符串轉義 (如寫入文件、構建特定格式字符串)。

總結

永遠使用參數化查詢 (PDO/MySQLi Prepared Statements) 防禦 SQL 注入。
addslashes()、mysql_real_escape_string() 皆為不推薦的拼接 SQL 時代產物,無法全面防禦現代注入向量。

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