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

SQL 注入攻擊與防禦實戰:從萬能密碼到 PDO 預處理

     編輯:MySQL 綜合教學

經典注入場景

1. 登入繞過(字串拼接)

$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

輸入:username: admin' --、password: 任意

實際執行:SELECT * FROM users WHERE username = 'admin' --' AND password = 'xxx' → 註解掉密碼驗證。

2. 數值型注入(無引號)

$sql = "SELECT * FROM users WHERE id = $id";

輸入:id: 1 UNION SELECT * FROM users

3. 搜尋 LIKE 注入

$sql = "SELECT * FROM goods WHERE name LIKE '%$keyword%'";

輸入:% → 回傳全表。

4. INSERT 注入

INSERT INTO users(username, password, grade) VALUES('$user', '$pass', '1');

輸入密碼:123', '9')/* → 竄改 grade 為 9。

防禦層級

層級方案優缺點
1️⃣php.ini: magic_quotes_gpc = On已棄用,PHP 5.4+ 移除,易被 char() 繞過
2️⃣查詢後應用層比對密碼需額外查詢,仍有二次注入風險
3️⃣PDO 預處理(推薦)參數化查詢,SQL 與資料分離,根治注入
4️⃣WAF/IDS 入侵檢測網路層攔截,規則維護成本高,作為纵深防禦

PDO 預處理實戰

$dsn = "mysql:host=localhost;port=3306;dbname=test;charset=utf8";
$pdo = new PDO($dsn, 'root', '123456');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = "SELECT * FROM users WHERE username = ? AND password = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username, $password]);
$user = $stmt->fetch();

if (!$user) {
    die('登入失敗');
}

PDO 核心優勢

  • 資料庫抽象層:同一套 API 支援 MySQL/PostgreSQL/SQLite 等。
  • 預處理機制:SQL 模板先編譯,參數後綁定,徹底杜絕注入。
  • 例外模式:ERRMODE_EXCEPTION 讓錯誤可被 try-catch 捕獲。

開發者安全清單

  1. 永不拼接 SQL,全面採用預處理/參數化查詢。
  2. 嚴格驗證輸入型別、長度、格式(白名單)。
  3. 資料庫帳號最小權限,Web 應用帳號僅 SELECT/INSERT/UPDATE/DELETE。
  4. 錯誤訊息不外露給前端,記錄至日志系統。
  5. 定期掃描慢查詢日志,發現異常 UNION SELECT、SLEEP() 等特徵。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved