攻擊者透過構造惡意輸入,改變 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;--'
mysqli_query 預設不支援多語句,單次注入無法直接執行 DELETE,但可透過 UNION SELECT 竊取資料、SLEEP() 盲注。'; DROP TABLE users;-- 直接生效,破壞力極大。PDO::MYSQL_ATTR_MULTI_STATEMENTS 預設關閉,但若開啟同樣危險。PHP ≤ 5.3 magic_quotes_gpc=On 自動對 $_GET/POST/COOKIE 加反斜線。缺點:不全面、雙重轉義、造成虛假安全感。PHP 5.4 移除,**不可依賴**。
$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 = 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();
filter_var, ctype_*, 正則)。SELECT/INSERT/UPDATE,無 DROP/ALTER/FILE/GRANT。display_errors=Off,log_errors=On,友善錯誤頁面。pg_escape_bytea() / pg_unescape_bytea()(類 Base64 編碼)。HEX()/UNHEX()。LIKE '%abc%' 模糊查詢,需在應用層或全文索引處理。GBK/Big5 等編碼中,部分字元第二位元組為 0x5c(反斜線),攻擊者可構造 %bf%27 繞過 addslashes。**根治:全鏈路 UTF-8 + 參數化查詢**。
SQL 注入防禦鐵律:永不拼接 SQL 字串,永遠使用參數化查詢。輔以輸入驗證、最小權限、錯誤隱藏、WAF、審計日誌,構建多層防禦體系。