建立 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);
}
}
?>
$getfilter:針對 GET 參數,包含單引號、SQL 關鍵字組合、註釋、Script 標籤、危險函數、DDL/DML 語句。$postfilter/$cookiefilter:稍微放寬單引號檢查,聚焦關鍵字與運算子組合。stopattack():將陣列值扁平化,執行 preg_match,命中則記錄 IP、時間、腳本、方法、參數鍵值。writeslog():追加寫入 CACHE_PATH/logs/sql_log.txt。<?php
require_once 'sqlsafe.class.php';
new sqlsafe(); // 實例化即啟動全域過濾
?>
⚠️ 警告: 純正則過濾屬於「黑名單」機制,存在繞過風險(編碼、大小寫、註釋變形等),且可能誤攔正常業務資料(如內容包含 "union" 的合法文字)。
<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
?>
htmlspecialchars(),而非輸入端過濾。此類適合**快速為老專案加裝基礎防護**、或作為**第二道防線**(參數化查詢為第一道)。新專案請優先採用參數化查詢。