本文目录导读:

- 核心拦截逻辑架构
- 基于Nginx + lua/正则的特征拦截
- 使用ModSecurity(推荐企业级方案)
- PHP层防御(作为第二道防线)
- 异常参数特征库动态更新方案
- 性能优化建议
- 实战案例:拦截常见攻击特征
- 总结建议
针对PHP项目的异常请求参数拦截,最有效的方式是在Web应用防火墙(WAF)层或Web服务器(Nginx/Apache)层进行特征匹配,而不是在PHP代码中逐行处理。
以下是详细的实现方案:
核心拦截逻辑架构
请求 → Nginx/Apache (ModSecurity) → PHP-FPM → PHP应用
↑ ↑
第一道防线 (特征库匹配) 第二道防线 (参数过滤)
基于Nginx + lua/正则的特征拦截
1 在nginx.conf中配置特征库
# 异常参数特征库(可独立成文件)
map $query_string $blocked_reason {
default "";
# SQL注入特征(核心规则)
~*"(union.*select|select.*from|insert\s+into|delete\s+from|drop\s+table|update.*set)" "SQL_INJECTION";
# XSS特征
~*"(<script|javascript:|onerror=|onclick=|onload=)" "XSS_ATTACK";
# 文件包含特征
~*"(\.\./|\.\.\\|/etc/passwd|/proc/self/cmdline)" "PATH_TRAVERSAL";
# 命令执行特征
~*"(\|.*cat\s+|\||;.*rm\s+|&&.*wget)" "COMMAND_INJECTION";
# 参数长度攻击
~*"(.{500,})" "PARAM_TOO_LONG";
}
# 应用拦截
server {
# ... 其他配置 ...
if ($blocked_reason != "") {
return 403 "Request blocked: $blocked_reason";
}
}
使用ModSecurity(推荐企业级方案)
1 安装ModSecurity扩展
# 编译安装(重点:需要连接OWASP核心规则集) git clone https://github.com/SpiderLabs/ModSecurity-nginx.git ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx make modules cp objs/ngx_http_modsecurity_module.so /usr/lib/nginx/modules/
2 核心规则集配置
# modsecurity.conf
SecRuleEngine On
# 引入OWASP核心规则集
Include /usr/local/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Include /usr/local/modsecurity/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
Include /usr/local/modsecurity/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
# 自定义高精度规则
SecRule REQUEST_URI|ARGS|ARGS_NAMES "@rx (union[\s]+select|select[\s]+from)" \
"id:100001,phase:2,deny,status:403,msg:'SQL Injection Detected'"
SecRule REQUEST_URI|ARGS "@rx (<script|javascript:)" \
"id:100002,phase:2,deny,status:403,msg:'XSS Attempt'"
PHP层防御(作为第二道防线)
1 请求参数检测中间件
<?php
class RequestParameterFilter {
private $blockedPatterns = [
'SQL_INJECTION' => [
'/(union.*select|select.*from)/i',
'/(insert\s+into|delete\s+from|drop\s+table)/i',
'/(update.*set)/i',
'/(or\s+1\s*=\s*1)/i'
],
'XSS_ATTACK' => [
'/<script\b[^>]*>/i',
'/javascript\s*:/i',
'/on\w+\s*=\s*"/i',
'/alert\s*\(/i'
],
'PATH_TRAVERSAL' => [
'/\.\.\//',
'/\.\.\\\\/',
'/\/etc\/passwd/',
'/\/proc\/self/'
],
'COMMAND_INJECTION' => [
'/;.*(cat|rm|wget|curl|ls)/',
'/\|\s*(cat|rm|wget)/',
'/&&\s*(wget|curl)/'
]
];
public function filterRequest() {
$requestParams = $_REQUEST;
foreach ($requestParams as $key => $value) {
if (is_string($value)) {
$this->checkParam($key, $value);
} elseif (is_array($value)) {
$this->checkRecursive($key, $value);
}
}
return true;
}
private function checkRecursive($key, $value) {
foreach ($value as $subKey => $subValue) {
if (is_string($subValue)) {
$this->checkParam($key . '[' . $subKey . ']', $subValue);
} elseif (is_array($subValue)) {
$this->checkRecursive($subKey, $subValue);
}
}
}
private function checkParam($key, $value) {
foreach ($this->blockedPatterns as $type => $patterns) {
foreach ($patterns as $pattern) {
if (preg_match($pattern, $value)) {
header('HTTP/1.1 403 Forbidden');
echo json_encode([
'code' => 403,
'message' => 'Request blocked: ' . $type . ' detected in parameter "' . $key . '"',
'timestamp' => time()
]);
exit;
}
}
}
}
}
// 在入口文件调用
$filter = new RequestParameterFilter();
$filter->filterRequest();
异常参数特征库动态更新方案
1 使用Redis存储动态规则
<?php
class DynamicRuleManager {
private $redis;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
// 添加新规则
public function addRule($type, $pattern, $action = 'block') {
$rule = [
'pattern' => $pattern,
'action' => $action,
'created_at' => time(),
'expire_at' => time() + 86400 // 默认24小时
];
$this->redis->hSet('waf_rules', $type . ':' . md5($pattern), json_encode($rule));
}
// 加载规则到内存
public function loadRules() {
$rules = $this->redis->hGetAll('waf_rules');
$activeRules = [];
foreach ($rules as $key => $ruleJson) {
$rule = json_decode($ruleJson, true);
if ($rule['expire_at'] > time()) {
$activeRules[$key] = $rule;
}
}
// 更新到全局配置
return $activeRules;
}
}
性能优化建议
1 使用布隆过滤器减少正则匹配
<?php
class BloomFilterChecker {
private $bitArray = [];
private $size = 1048576; // 1MB
public function check($param) {
$hash1 = crc32($param) % $this->size;
$hash2 = md5($param) % $this->size;
return $this->bitArray[$hash1] && $this->bitArray[$hash2];
}
}
2 配置缓存策略
# 在Nginx层启用缓存
proxy_cache_path /var/cache/nginx/levels keys_zone=waf:10m max_size=1g inactive=60m;
location /api/ {
# 对常见参数进行缓存
if ($args ~* "id=\d+&page=\d+") {
set $cache_key $host$request_uri$http_user_agent;
proxy_cache waf;
proxy_cache_key $cache_key;
proxy_cache_valid 200 5m;
}
}
实战案例:拦截常见攻击特征
1 SQL注入攻击拦截
# Nginx级别拦截
location ~* ^/api/ {
# 拦截含有union select的参数
if ($args ~* "(union[\s\+]+select|select[\s\+]+from)") {
return 403 "SQL Injection Detected";
}
# 拦截注释符攻击
if ($args ~* "(/\*|--|#|;|')") {
return 403 "SQL Comment Attack";
}
proxy_pass http://php_backend;
}
2 XSS攻击拦截
// PHP层强化过滤
function sanitizeInput($input) {
$patterns = [
'/<[^>]*script[^>]*>/i',
'/on\w+\s*=\s*"[^"]*"/i',
'/javascript\s*:\s*/i',
'/alert\s*\([^)]*\)/i',
'/document\.cookie/i'
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $input)) {
return json_encode([
'error' => 'XSS Attack Detected',
'blocked' => true
]);
}
}
return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}
总结建议
- 优先使用WAF层:ModSecurity + OWASP CRS是最成熟方案
- Nginx层越早拦截越好:避免PHP进程消耗
- 动态特征库:使用Redis存储,支持热更新
- 性能与安全的平衡:对高频请求使用布隆过滤器
- 日志审计:记录所有拦截事件,方便分析攻击模式
这种多层防御架构能有效拦截95%以上的异常请求参数攻击。