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

SQL 注入攻擊實戰分析:Union 查詢、登入繞過與防禦對策

     編輯:PHP 相關知識

SQL 注入攻擊向量完整剖析:從原理到防禦

SQL 注入發生於使用者輸入未經過濾直接拼接進 SQL 語句。本文分析 Union 查詢注入、登入繞過、錯誤回顯等經典手法,並給出完整防禦方案。

攻擊場景一:Union 查詢注入 (資料竊取)

<?php
// 易受攻擊代碼
$id = $_GET['id']; // 無過濾
$sql = "SELECT * FROM articles WHERE id = $id"; // 直接拼接
$result = mysql_query($sql);
?>

攻擊 Payload:

// 原始: SELECT * FROM articles WHERE id = 1
// 注入: id=1 AND 1=2 UNION SELECT 1,username,password,4,5 FROM admin--
// 結果: SELECT * FROM articles WHERE id = 1 AND 1=2 UNION SELECT 1,username,password,4,5 FROM admin--

條件:

  • 欄位數相同 (用 ORDER BY 1,2,3... 或 UNION SELECT NULL,NULL... 試探)。
  • 資料型別相容 (數字/字串/日期)。
  • 知道目標表名 (資訊洩露、猜測、information_schema 查詢)。

攻擊場景二:登入繞過 (認證繞過)

<?php
// 易受攻擊代碼
$user = $_POST['username'];
$pass = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = '$user' AND password = '$pass'";
$result = mysql_query($sql);
if (mysql_num_rows($result) > 0) { /* 登入成功 */ }
?>

經典 Payload:

輸入欄位值產生 SQL 片段
username' OR '1'='1username = '' OR '1'='1
password' OR '1'='1password = '' OR '1'='1
usernameadmin'--username = 'admin'-- (註解掉密碼檢查)
username' OR 1=1#username = '' OR 1=1# (MySQL 註解)

結果:WHERE 條件恆真,返回第一筆記錄 (通常是管理員),繞過驗證。

攻擊場景三:錯誤回顯注入 (資訊洩露)

<?php
// 開啟錯誤顯示 (生產環境嚴禁)
ini_set('display_errors', 1);
$id = $_GET['id'];
$sql = "SELECT * FROM products WHERE id = $id";
mysql_query($sql) or die(mysql_error()); // 直接輸出 SQL 錯誤
?>

攻擊者輸入 id=1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(VERSION(),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)-- 觸發重複鍵錯誤,將資料庫版本、表結構等資訊透過錯誤訊息洩露。

完整防禦策略

  1. 參數化查詢 / 預處理語句 (唯一根治)
    <?php
    // PDO
    $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
    $stmt->execute([$user, $pass]);
    
    // MySQLi
    $stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
    $stmt->bind_param('ss', $user, $pass);
    $stmt->execute();
    
  2. 輸入驗證與型別轉換 (纏深防禦)
    $id = (int)$_GET['id']; // 強制整數
    $email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
    
  3. 最小權限資料庫帳號:Web 應用帳號僅擁有 SELECT/INSERT/UPDATE/DELETE,無 DROP/ALTER/GRANT。
  4. 錯誤訊息不外露:
    ini_set('display_errors', 0);
    ini_set('log_errors', 1);
    ini_set('error_log', '/var/log/php_errors.log');
    
  5. WAF / 參數過濾:ModSecurity、Nginx Lua 腳本過濾常見攻擊特徵 (但非萬能,需配合上述措施)。
  6. ORM / Query Builder:Laravel Eloquent、Doctrine、Yii ActiveRecord 內建參數化,預設安全。

自動化檢測工具

  • sqlmap:開源、功能最全、支援各種注入類型、可導出資料、讀寫檔案、OS Shell。
  • OWASP ZAP:掃描器包含 SQLi 掃描規則。
  • PHPStan / Psalm:靜態分析偵測未使用預處理的查詢。

程式碼審計檢查清單

  • [ ] 所有 SQL 是否使用預處理語句?
  • [ ] 動態表名/欄位名是否有白名單驗證?
  • [ ] 錯誤訊息是否已關閉顯示?
  • [ ] 資料庫帳號權限是否最小化?
  • [ ] 是否有針對舊代碼 (mysql_*) 的遷移計畫?

SQL 注入是 OWASP Top 10 長年榜首,根治之道在於「資料與代碼分離」——參數化查詢。任何字串拼接 SQL 的代碼都是定時炸彈,請立即審查並修復。

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