网站漏洞防护中,Web应用防火墙(WAF)是第一道核心防线,但默认规则往往存在大量绕过可能。攻击者利用编码变换、分块传输、参数污染、协议层混淆等手段,可以轻松穿透标准化防护规则。要真正实现有效防护,必须基于业务特征自定义WAF规则,针对具体攻击向量做精准拦截,而不是依赖厂商通用策略。本文将从绕过原理、自定义规则编写、多层防护架构三个维度,给出可直接落地的实操方案。
一、WAF默认规则为什么容易被绕过
市面上主流WAF产品,包括云WAF和硬件WAF,出厂时都内置了一套通用检测规则库。这套规则基于已知攻击特征签名编写,比如SQL注入的经典关键字、XSS的常见标签组合。问题在于,攻击者只要对payload做轻微变形,就能让签名匹配失效。
具体来说,绕过手段主要有以下几类:第一是编码绕过,把恶意字符用URL编码、Unicode编码、双重编码、Base64编码等方式隐藏;第二是分块传输绕过,利用HTTP分块编码(Chunked Transfer Encoding)将攻击载荷拆成多个块发送,WAF如果只检测单个块就会漏判;第三是参数污染,在同一参数名后追加多个值,让WAF只检测到第一个无害值而放行;第四是大小写混写和注释符插入,比如在SQL语句中插入//注释打断关键字匹配;第五是利用协议本身的模糊地带,比如在请求头中使用非常规字段名传递恶意内容。
二、自定义WAF规则的核心思路
自定义规则的本质不是"写更多规则",而是"写更精准的规则"。核心原则有三条:第一,基于业务上下文做白名单限制,只允许业务必需的字符和格式;第二,对所有输入做归一化处理后再检测,先解码再匹配;第三,设置多层检测逻辑,单一规则失效时有兜底机制。
举个实际例子。假设你的网站有一个用户搜索功能,正常输入只会包含中文、英文、数字和空格。那么自定义规则就应该直接拒绝任何包含特殊符号(如单引号、分号、尖括号、等号)的请求,而不是试图去匹配"有没有SQL注入特征"。这种白名单策略比黑名单策略安全得多,因为攻击者无论如何变形,只要包含恶意字符就会被拦截。
三、针对常见绕过手法的自定义规则编写
下面按绕过类型逐一给出规则编写方法和示例。
1. 编码绕过防护规则
攻击者常用%27代替单引号、%3C代替小于号。自定义规则需要在WAF检测前强制进行URL解码,或者在规则中同时匹配编码后的形式。以ModSecurity为例,可以这样写:
SecRule REQUEST_URI|ARGS|ARGS_NAMES "@detectSQLi" \
"id:1001,\
phase:1,\
deny,\
status:403,\
log,\
msg:'SQL Injection Attempt Detected',\
chain"
SecRule REQUEST_URI|ARGS|ARGS_NAMES "@validateByteRange 32-126" \
"t:urlDecodeUni,\
t:lowercase"
这里的关键是t:urlDecodeUni和t:lowercase这两个转换操作符,它们会先对输入做URL解码和小写转换,然后再做正则匹配,这样编码绕过就失效了。
2. 分块传输绕过防护规则
分块传输绕过的核心是WAF没有正确重组HTTP请求体。自定义规则层面,需要确保WAF工作在完整请求体模式下,而不是流式检测模式。在规则中可以强制要求检测REQUEST_BODY而不是仅检测头部。同时可以添加规则拦截异常的Transfer-Encoding头:
SecRule REQUEST_HEADERS:Transfer-Encoding "!@eq 0" \
"id:1002,\
phase:1,\
deny,\
status:403,\
log,\
msg:'Chunked Transfer Encoding Blocked'"
这条规则直接拒绝任何使用分块传输的请求。对于不需要分块传输的普通Web应用来说,这是一个非常有效且误报率极低的策略。
3. 参数污染绕过防护规则
参数污染是指同一个参数名出现多次,比如?id=1&id=UNION SELECT。WAF如果只检测第一个值就会漏过。解决方案是检测参数是否重复出现,以及检测所有参数值的组合:
SecRule ARGS_NAMES "@gt 1" \
"id:1003,\
phase:1,\
deny,\
status:403,\
log,\
msg:'Parameter Pollution Detected'"
更严格的做法是检测ARGS_GET_NAMES或ARGS_POST_NAMES中是否有重复键名,一旦发现直接拒绝。这种规则对正常业务几乎没有影响,因为正常表单提交不会出现同名字段重复。
4. 大小写和注释符绕过防护规则
SQL注入中常见的手法是SeLeCt、UN//ION等。应对方法是在规则中使用不区分大小写的匹配,并且在检测前去除注释符。ModSecurity中可以用t:removeComments操作符:
SecRule ARGS "@detectSQLi" \
"id:1004,\
phase:2,\
deny,\
status:403,\
log,\
msg:'SQL Injection with Obfuscation',\
t:lowercase,\
t:removeComments,\
t:removeNulls"
t:removeComments会把/* */和--注释全部清除,t:removeNulls会清除%00截断符,这样攻击者的混淆手段就全部失效了。
四、构建多层防护架构
单靠WAF规则自定义是不够的,必须构建纵深防御体系。第一层是WAF层,负责流量清洗和已知攻击拦截;第二层是应用层,在代码中做输入验证和参数化查询,这是最终兜底;第三层是日志审计层,对所有被拦截的请求做详细记录和分析,持续优化规则。
在应用层,所有用户输入必须做严格的类型校验。比如ID参数只允许数字,用户名只允许字母数字下划线,邮箱用正则校验格式。数据库操作必须使用参数化查询或预编译语句,绝对不能拼接SQL。这些措施即使WAF被绕过,应用本身也不会被注入。
同时建议部署RASP(运行时应用自我保护)技术,它在应用内部运行,能检测到WAF层面看不到的逻辑漏洞和内存攻击。RASP和WAF配合使用,防护效果会大幅提升。
五、规则维护和持续优化
自定义规则不是写完就完事了,必须持续维护。建议每周分析WAF拦截日志,找出高频攻击类型和新出现的绕过手法。对于误报的请求,要分析原因并调整规则精度,而不是简单关闭规则。可以建立一个规则版本管理机制,每次修改都记录变更内容和原因。
另外,定期做渗透测试来验证WAF规则的有效性。可以用开源工具如sqlmap、nikto、wfuzz等对自己的系统做模拟攻击,看看哪些payload能穿透防护,然后针对性补充规则。这种红蓝对抗的方式是检验WAF规则质量最直接的手段。
六、常见误区和注意事项
很多人在自定义WAF规则时容易犯几个错误。第一是规则写得太宽泛,导致大量误报影响正常用户体验。解决方法是先在观察模式下运行规则,统计误报率后再切换到拦截模式。第二是只关注OWASP Top 10,忽略业务逻辑层面的攻击,比如越权访问、批量注册、接口滥用等。第三是忽略了WAF本身的性能影响,规则太多太复杂会导致请求延迟增加,需要在安全性和性能之间找平衡。
还有一点特别重要:WAF规则不能替代安全编码。它只是一道外部防线,如果应用代码本身存在漏洞,WAF被绕过只是时间问题。真正安全的系统一定是安全开发流程、代码审计、WAF防护、运行时保护多措并举的结果。
七、总结
Web应用防火墙的自定义规则是对抗绕过攻击的关键手段。核心方法论是:先理解绕过原理,再基于业务特征写精准规则,最后配合多层防御和持续优化形成闭环。不要迷信任何单一防护手段,安全是一个持续对抗的过程,规则要跟着攻击手法一起进化。把白名单策略放在优先位置,把编码归一化和多层检测作为基础能力,你的WAF才能真正扛住实战级别的攻击。
