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

PHP 與 SQL 注入攻擊:原理、實例與防禦全解析

     編輯:PHP 相關知識

什麼是 SQL 注入

攻擊者透過構造惡意輸入,改變 SQL 語句原本語義,竊取/篡改/刪除資料庫資料,甚至執行系統命令。OWASP Top 10 長年榜首。

經典攻擊範例

<?php
$name = $_GET['name']; // 攻擊者輸入:ilia'; DELETE FROM users;--
$sql = "SELECT * FROM users WHERE name = '{$name}'";
// 實際執行:SELECT * FROM users WHERE name = 'ilia'; DELETE FROM users;--'

資料庫驅動差異

  • MySQL (mysqli/mysqlnd):mysqli_query 預設不支援多語句,單次注入無法直接執行 DELETE,但可透過 UNION SELECT 竊取資料、SLEEP() 盲注。
  • PostgreSQL / SQLite:支援多語句,'; DROP TABLE users;-- 直接生效,破壞力極大。
  • PDO:PDO::MYSQL_ATTR_MULTI_STATEMENTS 預設關閉,但若開啟同樣危險。

PHP 內建防護:Magic Quotes(已移除)

PHP ≤ 5.3 magic_quotes_gpc=On 自動對 $_GET/POST/COOKIE 加反斜線。缺點:不全面、雙重轉義、造成虛假安全感。PHP 5.4 移除,**不可依賴**。

正確防禦:參數化查詢(唯一標準答案)

PDO

$pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false, // 真實預備語句
]);

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

MySQLi

$mysqli = new mysqli('127.0.0.1', 'user', 'pass', 'test');
$stmt = $mysqli->prepare('SELECT * FROM users WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();

補充防禦層(纵深防禦)

  1. 輸入驗證:白名單驗證型別、長度、格式、範圍(filter_var, ctype_*, 正則)。
  2. 最小權限資料庫帳號:Web 帳號僅擁有必要表的 SELECT/INSERT/UPDATE,無 DROP/ALTER/FILE/GRANT。
  3. 錯誤訊息不外洩:生產環境 display_errors=Off,log_errors=On,友善錯誤頁面。
  4. WAF:ModSecurity OWASP CRS、Cloudflare WAF 攔截已知攻擊載荷。
  5. ORM/Query Builder:Eloquent、Doctrine、ThinkPHP ORM 內建參數綁定,減少手寫 SQL。
  6. 審計日誌:記錄所有失敗登入、異常查詢、權限變更,配合 SIEM 告警。

二進位資料存儲特殊處理

  • PostgreSQL:pg_escape_bytea() / pg_unescape_bytea()(類 Base64 編碼)。
  • MySQL:參數化查詢直接綁定二進位字串,或 HEX()/UNHEX()。
  • 編碼後無法使用 LIKE '%abc%' 模糊查詢,需在應用層或全文索引處理。

多位元組字元編碼陷阱

GBK/Big5 等編碼中,部分字元第二位元組為 0x5c(反斜線),攻擊者可構造 %bf%27 繞過 addslashes。**根治:全鏈路 UTF-8 + 參數化查詢**。

總結

SQL 注入防禦鐵律:永不拼接 SQL 字串,永遠使用參數化查詢。輔以輸入驗證、最小權限、錯誤隱藏、WAF、審計日誌,構建多層防禦體系。

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