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

PHP SQL 注入防護:正則過濾方案與安全性分析

     編輯:PHP 相關知識

SQL 注入仍是 Web 應用首要風險。本文提供一套基於正則表達式的請求參數過濾類,並分析其優缺點與現代最佳實踐對比。

一、請求參數過濾類實現

<?php
class SqlInjectionFilter {
    private $patterns = [
        'get'    => "'|(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)",
        'post'   => "\\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)",
        'cookie' => "\\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)",
    ];

    public function __construct() {
        // 註冊自定義錯誤處理器,避免洩露路徑
        set_error_handler(function($errno, $errstr, $errfile, $errline) {
            error_log("[SQL_FILTER] {$errstr} in {$errfile}:{$errline}");
            die('Illegal operation detected');
        }, E_ERROR);
    }

    public function checkAll() {
        foreach ($_GET as $k => $v)   $this->check($k, $v, 'get');
        foreach ($_POST as $k => $v)  $this->check($k, $v, 'post');
        foreach ($_COOKIE as $k => $v) $this->check($k, $v, 'cookie');
    }

    private function check($key, $value, $type) {
        if (is_array($value)) $value = implode('', $value);
        // 白名單機制:包含 securityToken 的請求跳過檢查
        if (isset($_REQUEST['securityToken'])) return;
        if (preg_match("/{$this->patterns[$type]}/is", $value)) {
            $this->logAttack($key, $value, $type);
            die('Illegal operation!');
        }
    }

    private function logAttack($key, $value, $type) {
        $log = sprintf(
            "[%s] IP:%s | Type:%s | Key:%s | Value:%s\n",
            date('c'),
            $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            strtoupper($type),
            $key,
            $value
        );
        file_put_contents(__DIR__ . '/logs/sql_injection.log', $log, FILE_APPEND);
    }
}

// 使用方式:在入口檔案最早期實例化
// new SqlInjectionFilter()->checkAll();

二、常見攻擊特徵正則補充

$patterns = [
    'exec'      => '(?i)(?s)*exec\\s+\\(\\s*\\w+\\)',           // exec() 命令執行
    'xss_simple'=> '(?i)(?s)*(<|%3C)\\s*/?\\s*[a-z0-9%]+\\s*(>|%3E)', // 簡單 XSS
    'xss_eval'  => '(?i)(?s)*(%65|e)\\s*(%76|v)\\s*(%61|a)\\s*(%6C|l)', // eval 關鍵字編碼
    'xss_img'   => '(?i)(?s)*(<|%3C)\\s*(img|IMG)[^>]*(>|%3E)',      // 圖片標籤 XSS
    'xss_script'=> '(?i)(?s)*(%73|s)\\s*(%63|c)\\s*(%72|r)\\s*(%69|i)\\s*(%70|p)\\s*(%74|t)', // script 標籤編碼
    'sql_inject'=> '(?i)(?s)*((%27|\\')|(%3D|=)|(/|%2F)|(\\||%7C)|(%23|#)|(%3B|;))+' // SQL 特殊字符
];

三、方案局限性與現代最佳實踐

維度正則過濾方案參數化查詢(Prepared Statements)
防護原理黑名單匹配,攔截可疑字符白名單機制,數據與代碼分離
誤報率高(正常內容可能含關鍵字)極低
漏報風險高(繞過技巧層出不窮)極低(驅動層保證)
效能影響每請求多次正則匹配可復用執行計劃,效能更好
維護成本需持續更新正則一次編寫,長期有效

四、推薦的現代防護棧

  1. 核心防禦:全專案強制使用 PDO/MySQLi 預處理語句:
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
    $stmt->execute([$email, 1]);
  2. 輸入驗證:白名單驗證(型別、長度、格式、枚舉值),而非黑名單過濾。
  3. 最小權限:資料庫布號僅擁有必要權限(SELECT/INSERT/UPDATE),無 DROP/ALTER 權限。
  4. WAF 層面:部署 ModSecurity + OWASP CRS 或雲端 WAF(Cloudflare、阿里云盾)攔截已知攻擊特徵。
  5. 日誌審計:所有 SQL 錯誤、慢查詢、失敗登入記入結構化日誌(ELK),定期審計。
結論:正則過濾可作為「深度防禦」的輔助層(如攔截明顯掃描器流量),但絕不能作為唯一防線。參數化查詢才是 SQL 注入的根治方案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved