Web 应用防火墙 WAF 部署在应用与流量入口之间,按规则对请求做检测并拦截,常被用来缓解注入、XSS、路径遍历等注入与脚本类攻击。它是一道“前置过滤”,但兼顾误报与编码绕法有边界,须与代码层机制(参数化、输出编码)并用,而不是替代。分清“能挡什么、挡不住什么”是用好 WAF 的前提。
第六幕的第一个哨所立在入口。WAF 的价值是:很多攻击甚至走不到你的应用代码,在入口就被规则命中拦下,堪称“把风险挡在门外”。但它的口碑两极——用好了很香,用砸了要么误杀业务要么形同虚设。
WAF 站在前端与后端之间,对每个请求做语义检查:URL、参数、Cookie、请求体都过一遍,用一套规则库匹配签名、频率与行为特征,命中可疑即拦截、记录、放行或加验证码。它比代码层的校验更早、更通用——覆盖你还没意识到的接口与老功能。常见能力包括:
<script>、onerror 等,缓解 XSS 输入侧)。../、编码绕形)。用 WAF 的正确心态是“一道前置过滤”,而不是“安全完成了”。理由有二:
误报:规则宁可严也容易误杀正常业务——用户昵称里恰好含 <、合法查询里有 ',都可能被匹配成注入。因此要有放行名单、告警先行、灰度开启,避免把线上误伤成新的故障源。
漏报:任何规则库都吃不完所有编码绕法(大小写、URL 编码、Unicode 变体、分块入站),真实绕 WAF 的通杀载荷每年都有。它挡得住“常规流扫”,挡不住“针对性手工绕过”。
所以使用边界是:WAF 负责“在入口筛掉大路货、赚到早期告警”,真正的免疫靠参数化查询与输出编码、归属校验等代码层机制。两者互补,不可互相替代。
⚠️ 常见坑:买了 WAF 就把代码层那套停了,或反过来嫌 WAF 误报干脆全关。前者等于把地铁安检员撤了只留一个摆设,后者连第一道网都扔了。合理姿势是“WAF 前置 + 代码免疫”双轨并跑。
背景:一个直连后端的演示站,代码层未做参数化。操作一:未接 WAF 时提交一段 SQL 注入签名,观察是否落库失败/报错;操作二:把应用挂到 WAF 后面,同样载荷被 WAF 命中拦截。结果:接入后注入请求被拦在门外。解读:WAF 在入口截获并记录。变式:把 WAF 切到告警模式观察正常请求是否被误报,用放行名单消除误杀;再指出“WAF 加身但代码仍拼接 SQL”的组合,说明若攻击者绕过 WAF 直连后端,代码层仍会中招——验证“不能只靠 WAF”。
光报一句“今天拦了多少条”意义有限,真正的信号是“同一攻击源/同一载荷是否反复冲撞”。运维 WAF 值得盯三个读数:一,命中量在无业务变更时突然跳动,可能是新的扫描波次;二,同一 IP 段在短时间内集中命中,往往是定向攻击而非大路货扫描;三,命中里混着明显的人工试探(先探测再打),提示有人在手工测你。与其只看“总拦截数”,不如把以上三类“命中模式”联动日志告警,才能从早于业务受损的时间点看出攻击正在逼近——这也是 WAF 从“过滤器”升级成“哨所”的关键。
边界想清楚才能正确补位。WAF 天生挡不住三类:一是业务逻辑漏洞——默认口令、越权、重复领券这类“请求合法只是语义错”的,规则库根本没有对应的“签名”;二是加密或分流后无法语义化检测的请求(部分加密流量在入口只是密文);三是针对你专用接口的定制绕过——公开通杀载荷它认得出,冲着你的特殊参数精心手写的那一发的载荷,它未必见过。这三类恰恰是手册里强调“WAF 不能替代代码加固”的原因:把这三块交给参数化、归属校验、业务规则校验和威胁建模,WAF 只专心当第一道滤网,双方才各司其职。
很多团队把 WAF 一装就切拦截,结果第一次真实误报发生在业务高峰,教训惨重。给一个先行压测的节奏:先在镜像一份流量的预生产环境里开启“告警模式”,把线上一天的正常流量灌进去,数一数有多少条被误判命中——这一步专门暴露“规则太严会把正常请求砍掉”的问题;把误报的请求逐一放行名单、调规则,直到基本清零;确认无误后才在线上切拦截。上线后再持续看两类读数:拦截量是否和业务节奏吻合、有没有在无变更时突然跳动。让 WAF 在最坏的情况下先自己“体检”一遍,它才会在你真正需要它挡攻击时靠得住,而不是反过来扮演一台制造新故障的机器。
WAF 规则库和业务代码一样,会升级也会误伤,同样需要版本感和回滚能力。给三条建议:规则升级前先在预生产把新旧规则对比跑一遍,确认真实业务不被误伤;每次放规则变更记一笔变更记录与生效时间,出问题时能迅速知道“是那条新规则惹的祸”;保留一份“已知误报清单”,线上误伤时能对照快速定位放行还是收紧。把规则当成代码管,WAF 才不会在一次激进的规则升级后变成误杀业务的“帮凶”,也让“命中量异常”能回溯到是规则变更引起还是真有攻击在逼近。守好了版本与回归,WAF 这颗前沿哨所才既看得清敌人、又不误伤自己人。