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

PHP SQL 注入防護:基於正則的 GET/POST/COOKIE 參數過濾類別實作

     編輯:PHP 相關知識

防護原則

參數過濾屬於第二道防線(第一道是預處理語句/參數綁定)。本類別示範如何以正則攔截常見 SQL 注入特徵,並記錄攻擊日誌。

完整過濾類別


<?php
class SqlSafe {
    // GET 參數規則(較嚴格,含 script 標籤)
    private $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)";

    // POST/COOKIE 規則(稍寬鬆)
    private $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)";

    private $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)";

    public function __construct() {
        foreach ($_GET as $k => $v) $this->check($k, $v, $this->getFilter);
        foreach ($_POST as $k => $v) $this->check($k, $v, $this->postFilter);
        foreach ($_COOKIE as $k => $v) $this->check($k, $v, $this->cookieFilter);
    }

    private function check($key, $value, $pattern) {
        if (is_array($value)) $value = implode('', $value);
        if (preg_match("/$pattern/is", $value)) {
            $this->logAttack($key, $value);
            exit('非法參數,操作已記錄!'); // 或拋出異常
        }
    }

    private function logAttack($key, $value) {
        $log = sprintf(
            "%s %s %s %s %s %s\n",
            $_SERVER['REMOTE_ADDR'],
            date('Y-m-d H:i:s'),
            $_SERVER['PHP_SELF'],
            $_SERVER['REQUEST_METHOD'],
            $key,
            $value
        );
        $path = __DIR__ . '/logs/sql_inject.log';
        @file_put_contents($path, $log, FILE_APPEND | LOCK_EX);
    }
}

// 在入口檔案最早期實例化
new SqlSafe();

正則規則解析

片段攔截目標
'單引號閉合
(and|or)\b.+?(>|<|=|in|like)布林注入 1 or 1=1
/\*.+?\*/註釋截斷 /*
<\s*script\bXSS 腳本標籤
\bEXEC\b存儲過程執行
UNION.+?SELECT聯合查詢注入
UPDATE.+?SET|INSERT\s+INTO.+?VALUES資料竄改
(SELECT|DELETE).+?FROM資料竊取/刪除
(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)DDL 破壞

局限性與現代最佳實踐

  • 誤攔:正常內容含 "union"、"select" 等詞可能被誤判(如文章標題)。
  • 繞過:編碼、大小寫變形、註釋混淆等可繞過靜態正則。
  • 根本解法:全面使用預處理語句(PDO::prepare / mysqli_prepare),參數綁定徹底隔離代碼與資料。
  • 纵深防禦:WAF(ModSecurity)、資料庫權限最小化、錯誤訊息不外露、定期掃描審計。

現代 PDO 參數綁定範例


$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false, // 使用真實預處理
]);

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status = ?');
$stmt->execute([$_GET['email'], 1]);
$user = $stmt->fetch();
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved