去年秋天,防方案一个电商客户在凌晨两点被刷了 47 万次撞库请求。火墙WAF 日志里全是实施 200 状态码——它根本没拦住。事后复盘发现,测试规则库还停留在三个月前,防方案而攻击者用的火墙是一种刚流行起来的 JSON 嵌套绕过手法。这事让我意识到,实施WAF 上线不是测试插上网线就完事,实施测试才是防方案真正决定它能不能扛住的关键环节。
测试方案得从流量镜像开始。火墙别急着切生产流量,实施先做旁路部署,测试把真实业务流量复制一份给 WAF。防方案这一步能暴露很多问题:某次我们镜像了支付接口的火墙流量,发现 WAF 把微信回调的实施 XML 报文全标成了 XXE 攻击——误报率直接飙到 12%。如果直接串接上线,支付系统当场就挂了。旁路跑三天,观察误报和漏报的基线数据,比任何实验室测试都管用。
规则集要分两层测。第一层是 OWASP 核心规则,用 sqlmap 和 nuclei 跑一遍标准 payload,看拦截率。但别迷信这个数字,真实攻击者不会用现成的工具。第二层是自定义规则,得针对业务逻辑写。比如某政务系统有个文件下载接口,参数是 file_id=123,攻击者改成 file_id=123' AND 1=1-- 就能拖库。这种规则 WAF 厂商不会预置,必须自己抓包分析后手动添加。测试时用 Burp Suite 的 Intruder 模块,把参数位置、编码方式、大小写混写全试一遍。
性能测试容易被忽略。我们在一台 8 核 16G 的虚拟机上跑 WAF,开启全部规则后,QPS 从 12000 掉到 3400。更麻烦的是延迟——P99 从 8ms 涨到 210ms。后来发现是正则表达式回溯导致的,一条 .* 写法的规则在遇到长 URL 时疯狂消耗 CPU。解决办法是把规则拆成多条精确匹配,或者用 PCRE 的原子组语法。测试时用 wrk 或 locust 压测,同时开 top -H 看线程级 CPU 占用,能快速定位到是哪条规则在拖后腿。
绕过测试才是重头戏。WAF 最怕的是编码变形。比如 SELECT 被拦,那就试 %53%45%4C%45%43%54;还拦,就试 SEL/**/ECT 或者 SELECT 中间插 %00。有个客户用某云 WAF,我们通过 HTTP/2 的伪头部 :path 传 payload,直接绕过了所有规则——因为 WAF 只解析了 Host 和 User-Agent。这类测试得手动做,工具帮不上忙。每次绕过成功,就补一条规则,然后再试新的变形。循环三五轮,规则库才算有点样子。
日志和告警也得测。WAF 拦截了不代表完事,得确认日志里能还原攻击链。我们要求日志必须包含:原始请求的 X-Forwarded-For、匹配到的规则 ID、被截断的 payload 片段。有一次攻击者用分块传输编码(Transfer-Encoding: chunked)绕过检测,日志里只记了 blocked,没有原始数据,事后根本没法溯源。后来强制 WAF 在拦截时 dump 原始报文的前 512 字节,才解决这个问题。
最后一步是灰度上线。先切 5% 的流量到 WAF 串接模式,观察 24 小时。重点看两个指标:业务成功率有没有下降,以及 WAF 自身的 CPU 和内存是否稳定。某次灰度时发现,WAF 在处理大文件上传(>100MB)时会 OOM,原因是它把整个请求体读进内存做正则匹配。改成流式检测后问题消失。灰度期间还得准备回滚方案——一旦误杀率超过 0.5%,立刻切回旁路模式。
整个测试周期大概两周。别压缩,压缩了就是给攻击者留后门。我见过太多团队为了赶上线,跳过绕过测试和性能压测,结果 WAF 成了摆设。那 47 万的教训,够买好几套企业版 WAF 了。