WAF规则怎么写才有效?

wen 网络安全 53

本文目录导读:

WAF规则怎么写才有效?

  1. 有效规则的核心原则
  2. 针对Top攻击类型的规则写法(实战示例)
  3. 高级优化:减少误报与性能开销
  4. 一个“有效规则”的检查清单
  5. 避坑指南:千万别这样写

这是一个非常专业且切中要害的问题,很多安全团队(特别是甲方)在配置WAF时,容易陷入“规则越多越安全”或“直接开拦截模式”的误区,导致误报率飙升或绕过漏洞频出。

要写出有效的WAF规则,核心方法论是:基于攻击原理做“语义分析”,而不是基于特征做“关键词匹配”

以下是编写有效WAF规则的五个核心原则和具体实践指南:

有效规则的核心原则

  1. 精准打击,拒绝误报:规则应命中攻击语法,而非普通业务参数,拦截union select不如拦截union select [SQL语句](带空格、注释符或闭合符)。
  2. 分层防御:不要在入口层试图解决所有问题,规则应分三层:
    • 黑名单(已知攻击):拦截已知的Payload特征。
    • 白名单(业务例外):允许业务正常输入(如富文本、数学公式)。
    • 异常检测(未知攻击):基于语法、长度、熵值(信息熵)检测异常。
  3. 上下文感知:必须知道“参数”是干什么的。
    • ?id=1 只期待整数,出现字母应该直接拦截。
    • ?name=张三 期待中文,出现<script>应该拦截。
  4. 性能优先:复杂的正则表达式会导致WAF CPU飙升,拖垮源站。
    • 使用正则引擎优化(避免回溯爆炸)。
    • 尽量使用状态机树形匹配(如AC自动机)。
  5. 避免“万能规则”:不要写.*select.*.*drop.*这种规则,这会拦截掉所有包含“select”的正常业务(如“请选择城市”)。

针对Top攻击类型的规则写法(实战示例)

SQL注入(最核心,也最常写错)

  • 错误写法if (payload contains "select") { block },攻击者用SeLeCtsel/**/ectSELECT均可绕过。
  • 有效写法(基于词法和闭合):
    • 检测恒等式/\d+\s+(union|and|or)\s+\d+\s*[=<>]/i(拦截 1 and 1=1,但不拦截 1 and the year is 2023)。
    • 检测注释符: (拦截SQL注释,但不拦截正常代码中的“/*
    • 检测闭合括号:对于)或的异常出现次数,传入的参数中单引号数量为奇数且无业务必要,应告警。
    • 最佳实践WAF规则应该关注“SQL语法结构”的插入,而不是“关键词”。 优先使用WAF的SQL语义分析引擎(如果支持),而不是写正则。

XSS(跨站脚本攻击)- 防绕过难度高

  • 错误写法if (payload contains "<script>") { block }<img src=x onerror=alert(1)>直接绕过。
  • 有效写法(检测事件和协议):
    • 检测事件处理/\s(on\w+)\s*=/i (拦截 onerror=onload=onfocus= 等)。这是XSS规则里最核心的一条
    • 检测危险协议/javascript\s*:/i/data\s*:/i
    • 检测SVG/HTML标签嵌套/<\w+\s+[^>]*?\/?\s*>.*?<\/\w+>/i(针对富文本场景,需与白名单配合)。
    • CSS注入/expression\s*\(|behavio?r\s*:/i
  • 关键点:XSS规则一定要关注标签的闭合事件属性的冒号

命令注入

  • 有效写法:
    • 检测管道符与系统命令组合/[|;&$\n]+\s*(cmd|powershell|bash|sh|python|perl)/i`(注意,只匹配命令前缀而不是整个路径)。
    • 检测反引号: (反引号在Shell中是执行子命令,直接拦截)。
    • 检测写入操作/>(>)?|echo.*\|.*tee|wget.*-O/i(拦截写入文件的行为)。

文件包含/路径穿越

  • 有效写法:
    • 检测目录回溯: (必须是连续的两个点加斜杠)
    • 检测绝对路径/(?:^|\?|&)\w*=\/etc\//i(针对类似 ?file=/etc/passwd)。
    • 检测协议包含/(php|file|http|https|ftp):\/\//i(针对 include('http://evil.com/shell.txt'))。

高级优化:减少误报与性能开销

  1. 参数类型的精准分类

    • 数字型参数/^\d+$/(匹配通过,否则拦截)。
    • URL参数/^https?:\/\/[^\s<>]+$/i
    • 文本参数:去HTML化后再检测XSS规则。
  2. 白名单优先(非常重要)

    • 对于编辑器(TinyMCE, CKEditor)、接口文档(Swagger)、语言包等固定格式的请求,直接放行只做格式校验,不做深度检测。
  3. 响应检测(RCE & 数据泄露)

    • 有效规则:检查HTTP响应Body中是否包含 id=uid= 以及大段的<?phpSELECT...FROM
    • 应用场景:用于检测RCE的反弹结果SQL注入的盲注成功(当响应中的数据库信息出现时告警)。

一个“有效规则”的检查清单

写完规则后,请问自己三个问题:

  • 【绕过测试】:这条规则能被 、%0a(换行)、大小写、双写(<scr<script>ipt>)绕过吗?
  • 【误报测试】:这条规则会拦截“1.5版本”、“旧Select查询”、“
    标签”吗?
  • 【性能测试】:这条正则表达式在10000字长的文本上运行需要多久?(应< 0.1ms)

避坑指南:千万别这样写

  1. *禁止单条规则包含“.”匹配全量内容*(select|union|exec).*/i`,这会让WAF引擎陷入灾难性回溯,导致服务器CPU满载。
  2. 不要依赖关键词计数count("union") >= 1,攻击者用UNION ALL SELECT或穿袜子。
  3. 不要忽略协议层工具:WAF规则不要专门为ModSecurity的旧规则库而写,要参考OWASP CRS(核心规则集) 的最新版本(3.x及以上),它已经做了很好的语义化升级。

总结一句:最有效的WAF规则,不是“拦截所有看起来像攻击的字符”,而是“只允许符合业务逻辑的输入通过”。

如果你使用的是商业WAF(如Cloudflare、AWS WAF、阿里云WAF),请优先开启其内置的“托管规则”(Managed Rules),它们由安全团队持续更新,比自己写正则更好用,只针对自己业务的特有漏洞接口(如文件上传、API接口参数格式异常)编写自定义规则

抱歉,评论功能暂时关闭!