SQL 注入是 Web 應用中最常見也最危險的漏洞之一。本文提供一套完整的 PHP 防注入方案,涵蓋輸入過濾、參數類型檢查、SQL 關鍵字攔截等多層防護機制,適合在項目公共文件中引入,實現全站防護。
攻擊者通常遵循以下步驟:
xp_cmdshell 等擴展存儲過程執行系統命令在公共配置文件中引入,自動處理 $_GET、$_POST、$_COOKIE、$_FILES 及 $_SERVER 超全局變量。
<?php
// 判斷 magic_quotes_gpc 狀態,避免重複轉義
if (@get_magic_quotes_gpc()) {
$_GET = sec($_GET);
$_POST = sec($_POST);
$_COOKIE = sec($_COOKIE);
$_FILES = sec($_FILES);
}
$_SERVER = sec($_SERVER);
/**
* 遞歸處理數組/字符串/數值
* @param mixed $array
* @return mixed
*/
function sec(&$array) {
if (is_array($array)) {
foreach ($array as $k => $v) {
$array[$k] = sec($v);
}
} elseif (is_string($array)) {
$array = addslashes($array); // 字符串轉義
} elseif (is_numeric($array)) {
$array = intval($array); // 數值強制整型
}
return $array;
}
?>
針對 id=123 這類數值型參數,結合注入特征檢測與類型強制轉換:
/**
* 整型參數安全檢查
* @param mixed $id
* @return int
*/
function num_check($id) {
if (!$id) {
die('參數不能為空!');
}
if (inject_check($id)) {
die('非法參數:疑似 SQL 注入');
}
if (!is_numeric($id)) {
die('非法參數:必須為數字');
}
return intval($id);
}
/**
* 普通字符串過濾:注入檢測 + HTML 實體編碼
*/
function str_check($str) {
if (inject_check($str)) {
die('非法參數');
}
return htmlspecialchars($str);
}
/**
* 搜索關鍵詞過濾:過濾通配符 _ 和 %,防 LIKE 注入
*/
function search_check($str) {
$str = str_replace('_', '\_', $str);
$str = str_replace('%', '\%', $str);
return htmlspecialchars($str);
}
/**
* 表單長度限制
*/
function post_check($str, $min = 0, $max = 0) {
if ($min && strlen($str) < $min) die("最少 {$min} 字節");
if ($max && strlen($str) > $max) die("最多 {$max} 字節");
return stripslashes_array($str);
}
使用正則匹配高危 SQL 關鍵字,注意 eregi 在 PHP 5.3+ 已棄用,建議改用 preg_match / i 模式:
/**
* SQL 注入特征檢測
* @param string $sql_str
* @return bool
*/
function inject_check($sql_str) {
// 檢測 select, insert, update, delete, union, 註釋符, 路徑遍歷等
$pattern = '/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/i';
return preg_match($pattern, $sql_str);
}
/**
* 遞歸去除反斜線(配合 magic_quotes_gpc 使用)
*/
function stripslashes_array(&$array) {
if (is_array($array)) {
foreach ($array as $k => $v) {
$array[$k] = stripslashes_array($v);
}
} elseif (is_string($array)) {
$array = stripslashes($array);
}
return $array;
}
safe.inc.php,在項目入口文件(如 config.inc.php)中 require_once 'safe.inc.php';num_check()、str_check()、search_check() 等函數進行二次驗證。display_errors,避免錯誤信息洩露資料庫結構。這套方案兼顧了自動過濾與業務邏輯驗證,能有效抵禦大多數自動化掃描工具與手工注入嘗試。實際部署時請結合 WAF、資料庫最小權限原則等纵深防禦措施。