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

PHP SQL 注入漏洞原理與實例深度解析

     編輯:PHP 相關知識

什麼是 SQL 注入

SQL 注入 是攻擊者通過構造惡意輸入,改變原本 SQL 語句的語義,從而竊取、篡改、刪除數據庫數據,甚至獲取服務器控制權的攻擊手段。它是 Web 應用中最危險、最普遍的漏洞之一。

注入步驟

  1. 尋找注入點:URL 參數、表單字段、Cookie、HTTP Header 等所有外部輸入入口。
  2. 構造惡意載荷:利用 SQL 語法特性(注释、聯合查詢、布爾盲注、時間盲注等)。
  3. 提交載荷:通過正常業務流程發送給服務器。
  4. 數據庫執行:DBMS 將拼接後的 SQL 解析執行。
  5. 獲取結果:通過頁面回顯、報錯、響應時間差異等副作用獲取數據。

經典實例:登錄繞過

易受攻擊代碼

<?php
$name = $_POST['username'];
$pwd  = $_POST['password'];
$sql = "SELECT * FROM users WHERE username='$name' AND password=MD5('$pwd')";
$query = mysql_query($sql);
if (mysql_fetch_array($query)) {
    header('Location: admin.php');
} else {
    echo '登錄失敗';
}

攻擊載荷

用戶名輸入:' OR 1=1 #
密碼任意輸入。

拼接後的 SQL

SELECT * FROM users WHERE username='' OR 1=1 #' AND password=MD5('xxx')

原理解析

  • ' 閉合前面的單引號。
  • OR 1=1 恆為真,導致 WHERE 條件永遠滿足。
  • # 註釋掉後續所有內容(MySQL 中 # 為行註釋)。
  • 最終等價於 SELECT * FROM users,返回第一行記錄(通常是管理員),登錄成功。

防禦核心原則

1. 參數化查詢 / 預處理語句(首選)

數據與代碼分離,數據庫驅動層負責轉義,徹底杜絕注入。

<?php
// PDO 示例
$stmt = $pdo->prepare("SELECT * FROM users WHERE username=? AND password=MD5(?)");
$stmt->execute([$_POST['username'], $_POST['password']]);
$user = $stmt->fetch();

2. ORM / 查詢構建器

現代框架(Laravel Eloquent、ThinkPHP Db、Yii ActiveRecord)底層均使用參數化,正常使用安全。

User::where('username', $name)->where('password', md5($pwd))->first();

3. 輸入驗證與白名單

對預期為數字、枚舉、郵箱等的字段,嚴格校驗格式,拒絕非預期字符。

4. 最小權限原則

Web 應用數據庫賬號僅授予必要表的 SELECT/INSERT/UPDATE/DELETE,禁止 DROP、CREATE、FILE 等高危權限。

5. 錯誤信息不外露

生產環境關閉 display_errors,記錄日志不顯示用戶,避免報錯回顯洩露表結構。

進階注入類型速覽

類型特徵示例載荷
聯合查詢注入利用 UNION 合併結果集' UNION SELECT 1,username,password FROM admin #
報錯注入利用數據庫報錯回顯數據' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT @@version))) #
布爾盲注頁面無回顯,通過真/假邏輯判斷' AND (SELECT SUBSTRING(password,1,1) FROM admin)='a' #
時間盲注利用 SLEEP/BENCHMARK 延遲判斷' AND IF(1=1, SLEEP(3), 0) #
二次注入惡意數據存儲後,二次使用時觸發註冊用戶名 admin'--,後續修改密碼時注入

自動化檢測工具

  • sqlmap:功能最全的開源注入檢測利器,支持所有主流數據庫與注入類型。
  • OWASP ZAP:綜合 Web 掃描器,包含 SQLi 掃描插件。
  • 框架內置:Laravel DB::listen、ThinkPHP Db::listen 可記錄慢/異常 SQL。

總結

SQL 注入的根源是**數據與代碼未分離**。堅持使用參數化查詢、ORM、嚴格輸入驗證、最小權限、隱藏錯誤信息,可構建強有力的防禦體系。安全無絕對,持續代碼審計、漏洞掃描、應急預案缺一不可。

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