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

PHP SQL 注入攻擊與防禦:正則偵測模式與實戰防護策略

     編輯:PHP 相關知識

前言

SQL 注入仍是 OWASP Top 10 長年佔據前列的資安弱點。本文從攻擊者視角解析基於正則的盲注手法,並提供 PHP 端的偵測與防禦程式碼,幫助開發者建立多層次防護體系。

一、攻擊原理:利用 information_schema 進行盲注

MySQL 5+ 的 information_schema 資料庫儲存了所有資料庫、資料表、欄位的中繼資料。攻擊者可透過布林盲注逐字推斷表名:

攻擊步驟示範

-- 1. 判斷第一個表名首字是否在 a-z 範圍
id=1 AND 1=(SELECT 1 FROM information_schema.tables 
    WHERE TABLE_SCHEMA="blind_sqli" 
    AND table_name REGEXP '^[a-z]' LIMIT 0,1) /*

-- 2. 縮小範圍至 a-n
id=1 AND 1=(SELECT 1 FROM information_schema.tables 
    WHERE TABLE_SCHEMA="blind_sqli" 
    AND table_name REGEXP '^[a-n]' LIMIT 0,1) /*

-- 3. 確定首字為 n
id=1 AND 1=(SELECT 1 FROM information_schema.tables 
    WHERE TABLE_SCHEMA="blind_sqli" 
    AND table_name REGEXP '^n' LIMIT 0,1) /*

-- 4. 遞迴推斷完整表名:news
'^n[a-z]' → '^ne[a-z]' → '^new[a-z]' → '^news[a-z]' → FALSE
驗證:table_name = 'news'

-- 5. 猜解下一個表:LIMIT 1,1 → LIMIT 2,1 ...

核心正則語法:

  • ^ 字串開頭
  • [a-z] 字元範圍
  • REGEXP MySQL 正則比對運算子

二、常見攻擊特徵正則模式

以下正則可用於 WAF、PHP 過濾器偵測常見攻擊向量:

<?php
// 命令執行特徵
$Exec_Commond = "(s|S)*(exec(s|+)+(s|x)pw+)(s|S)*";

// XSS 腳本標籤
$Simple_XSS   = "(s|S)*((%3C)|<)((%2F)|/)*[a-z0-9%]+((%3E)|>)(s|S)*";
$Eval_XSS     = "(s|S)*((%65)|e)(s)*((%76)|v)(s)*((%61)|a)(s)*((%6C)|l)(s|S)*";
$Image_XSS    = "(s|S)*((%3C)|<)((%69)|i|I|(%49))((%6D)|m|M|(%4D))((%67)|g|G|(%47))[^n]+((%3E)|>)(s|S)*";
$Script_XSS   = "(s|S)*((%73)|s)(s)*((%63)|c)(s)*((%72)|r)(s)*((%69)|i)(s)*((%70)|p)(s)*((%74)|t)(s|S)*";

// SQL 注入綜合特徵(含編碼繞過)
$SQL_Injection = "(s|S)*((%27)|(')|(%3D)|(=)|(/)|(%2F)|(")|((%22)|(-|%2D){2})|(%23)|(%3B)|(;))+(s|S)*";
?>

三、PHP 端防禦實作:請求過濾器

<?php
// 自訂錯誤處理
function customError($errno, $errstr, $errfile, $errline) {
    echo "<b>Error number:</b> [$errno], error on line $errline in $errfile<br />";
    die();
}
set_error_handler("customError", E_ERROR);

// GET/POST/COOKIE 過濾規則
$getfilter = "'|(and|or)\b.+?(>|<|=|in|like)|/\*.+?\*/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";

$postfilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";

$cookiefilter = "\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";

// 統一攔截函式
function StopAttack($StrFiltKey, $StrFiltValue, $ArrFiltReq) {
    if (is_array($StrFiltValue)) {
        $StrFiltValue = implode($StrFiltValue);
    }
    
    // 白名單機制:攜帶 securityToken 的請求略過檢查
    if (preg_match("/" . $ArrFiltReq . "/is", $StrFiltValue) == 1 && !isset($_REQUEST['securityToken'])) {
        // 記錄攻擊日誌
        slog("<br><br>攻擊 IP: " . $_SERVER["REMOTE_ADDR"] . "<br>攻擊參數: " . $StrFiltKey . "<br>攻擊內容: " . $StrFiltValue);
        exit("非法請求已攔截");
    }
}

// 對所有超全域變數套用過濾
foreach ($_GET as $key => $value) StopAttack($key, $value, $getfilter);
foreach ($_POST as $key => $value) StopAttack($key, $value, $postfilter);
foreach ($_COOKIE as $key => $value) StopAttack($key, $value, $cookiefilter);
?>

四、根本防禦:參數化查詢(最佳實踐)

正則過濾只能作為輔助防線,核心防禦必須使用預處理語句:

PDO 範例(推薦)

<?php
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// 安全查詢:參數綁定
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username AND status = :status");
$stmt->execute([
    ':username' => $_GET['username'],
    ':status'   => 1
]);
$user = $stmt->fetch();
?>

MySQLi 範例

<?php
$mysqli = new mysqli("localhost", $user, $pass, "test");
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $_GET['username']);
$stmt->execute();
$result = $stmt->get_result();
?>

五、多層次防護架構建議

層級措施工具/技術
網路層WAF 規則攔截ModSecurity、Cloudflare WAF、OpenResty + Lua
應用層參數化查詢(核心)PDO / MySQLi Prepared Statements
應用層輸入驗證與白名單filter_var、Respect\Validation、嚴格型別提示
應用層ORM/Query BuilderEloquent、Doctrine、Medoo(內建參數化)
資料庫層最小權限原則僅授予 SELECT/INSERT/UPDATE,禁止 DROP/ALTER
資料庫層錯誤訊息隱藏關閉 display_errors,自訂錯誤頁面
監控層攻擊日誌與告警ELK Stack、Sentry、自建審計表

六、常見誤區提醒

  • ❌ addslashes() / mysql_real_escape_string():編碼問題導致繞過,已棄用
  • ❌ 依賴單一正則過濾:繞過技巧層出不窮(編碼、註釋、大小寫、空白變形)
  • ❌ 信任前端驗證:前端攔截只能改善 UX,無法防禦直接發送的惡意請求
  • ✅ 參數化查詢 + 嚴格型別 + 最小權限 = 根本解決

總結

理解基於正則的 SQL 盲注原理有助於建立威脅模型,但實務防禦的核心永遠是參數化查詢。正則過濾、WAF、輸入驗證屬於纵深防禦的輔助層。建立「不信任任何輸入」的開發文化,配合代碼審查與自動化掃描,才能有效降低 SQL 注入風險。

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