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

PHP SQL 注入防護:非法字元過濾類實作

     編輯:PHP 綜合知識

SQL 防護類設計思路

建立 sqlsafe 類,於建構子自動掃描 $_GET、$_POST、$_COOKIE,以正則白名單/黑名單混合模式攔截疑似 SQL 注入、XSS 攻擊載荷,並記錄攻擊日誌。

完整類別代碼

<?php
class sqlsafe {
    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)\";
    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 $key => $value) {
            $this->stopattack($key, $value, $this->getfilter);
        }
        foreach ($_POST as $key => $value) {
            $this->stopattack($key, $value, $this->postfilter);
        }
        foreach ($_COOKIE as $key => $value) {
            $this->stopattack($key, $value, $this->cookiefilter);
        }
    }

    public function stopattack($StrFiltKey, $StrFiltValue, $ArrFiltReq) {
        if (is_array($StrFiltValue)) {
            $StrFiltValue = implode($StrFiltValue);
        }
        if (preg_match(\"/\" . $ArrFiltReq . \"/is\", $StrFiltValue) == 1) {
            $this->writeslog($_SERVER[\"REMOTE_ADDR\"] . \" \" . strftime(\"%Y-%m-%d %H:%M:%S\") . \" \" . $_SERVER[\"PHP_SELF\"] . \" \" . $_SERVER[\"REQUEST_METHOD\"] . \" \" . $StrFiltKey . \" \" . $StrFiltValue);
            showmsg('您提交的參數非法,系統已記錄您的本次操作!', '', 0, 1);
        }
    }

    public function writeslog($log) {
        $log_path = CACHE_PATH . 'logs' . DIRECTORY_SEPARATOR . 'sql_log.txt';
        $ts = fopen($log_path, \"a+\");
        fputs($ts, $log . \"\r\n\");
        fclose($ts);
    }
}
?>

關鍵邏輯解析

1. 多層過濾規則

  • $getfilter:針對 GET 參數,包含單引號、SQL 關鍵字組合、註釋、Script 標籤、危險函數、DDL/DML 語句。
  • $postfilter/$cookiefilter:稍微放寬單引號檢查,聚焦關鍵字與運算子組合。

2. 攻擊攔截與日誌

  • stopattack():將陣列值扁平化,執行 preg_match,命中則記錄 IP、時間、腳本、方法、參數鍵值。
  • writeslog():追加寫入 CACHE_PATH/logs/sql_log.txt。

3. 入口引用方式

<?php
require_once 'sqlsafe.class.php';
new sqlsafe(); // 實例化即啟動全域過濾
?>

局限性與現代防護建議

⚠️ 警告: 純正則過濾屬於「黑名單」機制,存在繞過風險(編碼、大小寫、註釋變形等),且可能誤攔正常業務資料(如內容包含 "union" 的合法文字)。

現代最佳實踐

  1. 參數化查詢(Prepared Statements):使用 PDO 或 MySQLi 預處理語句,徹底分離代碼與資料。
    <?php
    $stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
    $stmt->execute([$email]);
    ?>
  2. ORM / Query Builder:框架內建查詢建構器自動處理轉義。
  3. 輸出編碼:防 XSS 應在輸出端用 htmlspecialchars(),而非輸入端過濾。
  4. WAF 層面防護:Nginx/ModSecurity 規則攔截明顯攻擊特徵。

適用場景

此類適合**快速為老專案加裝基礎防護**、或作為**第二道防線**(參數化查詢為第一道)。新專案請優先採用參數化查詢。

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