根本原因是WAF规则太宽泛且未考虑PHP解析前的原始请求特征,如不区分大小写、忽略注释绕过、未校验上下文,导致误拦JSON字段、Base64参数及富文本等内容。
为什么 phpwaf 会把正常请求当攻击拦掉?
根本原因是规则太宽泛,比如用正则匹配 union select 时没区分大小写、没考虑注释绕过、也没校验上下文。常见误拦场景包括:含 SQL 关键字的 JSON 字段(如 {"type": "union"})、URL 带 Base64 编码参数(解码后触发规则)、CMS 后台编辑器提交含 的富文本内容。
更隐蔽的问题是 WAF 在 PHP 请求解析前就介入——它看到的是原始 $_SERVER['REQUEST_URI'] 和原始 POST body,而没等 PHP 做 urldecode() 或 json_decode()。所以你代码里处理得再干净,WAF 已经在网关层“先斩后奏”了。
怎么精准放行特定 URL 或参数?
优先查 WAF 配置文件里是否支持白名单规则(不是 PHP 代码里加 bypass,是在 WAF 层配置)。典型做法:
- 对固定路径放行:在规则配置中加
location /api/v2/submit→ 跳过 SQL 注入检测模块 - 对特定参数放行:只忽略
content字段的 XSS 检测,其他字段(如title)仍检查,配置项类似skip_param content - 用条件匹配放行:例如
if ($request_method == 'POST' && $uri ~ ^/webhook/ ) { skip_rule 1001; }
注意:不同 phpwaf 实现(如 mod_security + php 插件、或自研中间件)语法差异大,别直接套 Nginx 规则到 Apache 模块里。
立即学习“PHP免费学习笔记(深入)”;