所有來自 $_GET、$_POST、$_COOKIE、$_REQUEST、$_SERVER、$_FILES 的數據均視為「污染數據」,必須經過驗證/過濾後才能進入業務邏輯、數據庫或輸出頁面。
| 場景 | 推薦函數/方法 | 說明 |
|---|---|---|
| SQL 防注入 | 預處理語句 | PDO::prepare / mysqli_prepare,參數綁定徹底解決注入 |
| HTML 輸出防 XSS | htmlspecialchars($str, ENT_QUOTES, 'UTF-8') | 轉義 < > & ' ",編碼必須指定 |
| Shell 命令參數 | escapeshellarg() / escapeshellcmd() | 防命令注入 |
| 整數驗證 | filter_var($v, FILTER_VALIDATE_INT) | 嚴格類型檢查 |
| 浮點數驗證 | filter_var($v, FILTER_VALIDATE_FLOAT) | |
| 郵箱格式 | filter_var($v, FILTER_VALIDATE_EMAIL) | RFC 5322 兼容 |
| URL 格式 | filter_var($v, FILTER_VALIDATE_URL) | |
| IP 地址 | filter_var($v, FILTER_VALIDATE_IP) | 支援 IPv4/IPv6、私有/保留標誌 |
| 移除標籤 | strip_tags($str, '<p><br>') | 保留允許標籤,屬性仍可能含事件處理器 |
| 路徑遍歷防護 | basename() / realpath() + 白名單 | 禁止 ../ 等目錄跳轉 |
<?php
// 定義允許的字段與規則
$rules = [
'username' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^[a-zA-Z0-9_]{3,16}$/']],
'age' => ['filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1, 'max_range' => 120]],
'email' => ['filter' => FILTER_VALIDATE_EMAIL],
'role' => ['filter' => FILTER_VALIDATE_REGEXP, 'options' => ['regexp' => '/^(admin|editor|viewer)$/']],
];
// 統一過濾輸入
$clean = filter_input_array(INPUT_POST, $rules);
// 檢查是否有驗證失敗
$errors = [];
foreach ($clean as $key => $value) {
if ($value === false || $value === null) {
$errors[] = "字段 {$key} 驗證失效或缺失";
}
}
if ($errors) {
// 返回錯誤,拒絕處理
exit(json_encode(['code' => 400, 'msg' => implode('; ', $errors)]));
}
// 此處 $clean 僅包含通過驗證的純淨數據
processBusiness($clean);
<?php
// 全局入口文件頂部引入
if (@get_magic_quotes_gpc()) {
$_GET = stripSlashesDeep($_GET);
$_POST = stripSlashesDeep($_POST);
$_COOKIE = stripSlashesDeep($_COOKIE);
$_FILES = stripSlashesDeep($_FILES);
}
// 統一轉義(僅用於極舊代碼無法改造時)
function addSlashesDeep(&$val) {
if (is_array($val)) {
foreach ($val as &$v) addSlashesDeep($v);
} elseif (is_string($val)) {
$val = addslashes($val);
}
return $val;
}
// 危險函數檢查(僅作最後防線)
function injectCheck(string $str): bool {
$patterns = [
'/union\s+select/i', '/select.*from/i', '/insert\s+into/i',
'/update.*set/i', '/delete\s+from/i', '/drop\s+table/i',
'/load_file/i', '/into\s+outfile/i', '/\.\.\//', '/\.\.\\\\/'
];
foreach ($patterns as $p) {
if (preg_match($p, $str)) return true;
}
return false;
}
警告:magic_quotes_gpc 已在 PHP 5.4 移除,addslashes 無法防禦所有注入(如編碼繞過),務必遷移至預處理語句。
htmlspecialchars($str, ENT_QUOTES, 'UTF-8')json_encode($str)(自動處理引號、換行、Unicode)cssesc()(需引入 polyfill)urlencode($str) / rawurlencode()escapeshellarg($str)Laravel、Symfony、ThinkPHP 等框架提供:
新項目強制使用框架內置機制,避免手工拼裝安全代碼。