ReDoS 正则回溯型拒绝服务攻击:从一个危险模式到 10 亿次尝试

导语:一条精心构造的字符串输入,配合一段看上去人畜无害的正则表达式,就能把服务器 CPU 拉满到 100%——这就是 ReDoS(正则表达式拒绝服务)。它不依赖漏洞,只依赖开发者写代码时的一个微小疏忽。这篇文章拆解它的原理、危险模式与实战打法。

ReDoS 灾难性回溯指数级爆炸示意图

一、原理:为什么正则会让 CPU 100%

正则引擎匹配失败时会回溯——它会撤销上一步的匹配,尝试新的组合。对大部分正则来说,回溯几次就能判断成功或失败。但当正则写成 ^(w+s?)*$ 这种嵌套量词形式时,回溯次数会指数级爆炸。

以简化版 ^(d+)*$ 匹配字符串 123456789z 为例:引擎要把 9 个数字分成若干段,每种切分方式都尝试一遍。结果是:

  • n=9:511 种组合
  • n=20:约 100 万种组合
  • n=30:约 10 亿种组合

字符每加一位,匹配时间指数级增长。一条 30 位的精心构造字符串,能把 V8 引擎打挂。服务端正则验证型接口中招,就是经典的 DoS。

二、危险正则的三大特征

实战中能打的 ReDoS 正则,都逃不开这三种构造:

  • 嵌套量词(a+)+(w+s?)*,外层量词套内层量词是最大元凶
  • 重叠字符类(d|d+)(w|.)*,多种匹配路径走同一条字符
  • 贪婪 + 锚定失败:贪婪量词配 ^...$ 锚定,匹配失败时回溯代价最高

只需源码里出现上述任意一种模式,这个端点就有 ReDoS 的潜质。看几个真实代码里的高危模式:

// 手机号校验(危险)
/^(0|[1-9][0-9]*)+$/

// 邮箱校验(危险)
/^([a-zA-Z0-9]+)*@example.com$/

// URL 校验(危险)
/^(w+://)?[w.-]+(:d+)?(/.*)?$/

// 用户名校验(危险)
/^([a-zA-Z0-9_]+)*$/

对应的攻击 payload 也朴素:aaaaaaaaaaaaaaaaaaaa!、40 位字母末尾加一个非预期字符,就能把匹配时间从毫秒拉到分钟级。

三、多语言引擎的差异

不是所有正则引擎都会被 ReDoS 拿下。V8 引擎 8.8 之后、Google Chrome 88+、Python 3.11+ 引入了一部分防御机制,能识别部分灾难性回溯并提前终止。但Firefox 的 SpiderMonkey、Java 的 java.util.regex、PHP 的 PCRE、Ruby 的 Onigmo 至今仍是高危目标——尤其是 Java 服务端,PCRE 的贪婪回溯是默认行为。

测试时务必针对目标栈选择对应引擎:JVM 服务跑的是 PCRE,Node.js 是 V8,Python 3.11 以下是 backtracking 实现。跨语言通用的高危模式就那几个。

四、实战方法:白盒、灰盒、黑盒三套打法

白盒(源代码审计):拿到源码后,全局搜 RegExp(new RegExpPattern.compile,定位所有正则定义;再人工过一遍危险模式。手机号、邮箱、URL、用户名这类输入校验正则最值得看。

灰盒(前端 JS 审计):没源码但能拿到前端资源时,搜索 JS 文件里的 RegExp( 调用,还原后端的正则定义。这种打法在 SaaS(软件即服务)应用中特别常见——前端公开的 JS 里经常带业务规则。

黑盒(模糊测试):直接构造长字符串加非预期字符(如 aaaaaaaaaaaaaaaaaaaa!)打到疑似校验接口,观察响应时间是否线性/指数级增长。响应从毫秒级跳到秒级甚至超时,基本实锤。

五、评估工具与真实案例

GitHub 上的 2bdenny/ReScue 工具专门干这件事:丢一个正则进去,它告诉你是否危险,并生成一条能让该正则进入回溯灾难的字符串。渗透测试时这是省时间利器。

六、防御:三个层面同时下手

代码层:把嵌套量词拆掉,把 s? 改成 s,把 (a+)+ 改成 a+。正则重构是最根本的解决方式。

运行时层:所有正则调用强制设置超时熔断(如 RE2 引擎、Go 的 regexp 包、PCRE 的 PCRE_EXTRA_MATCH_LIMIT 选项),超过阈值直接抛错并熔断接口。

架构层:在 WAF(Web 应用防火墙)/API 网关层对用户输入做长度限制(如手机号限 11 位、邮箱限 64 位),从源头切断长字符串攻击面。


原文出处:本系列基于 harsh-bothra/learn365 仓库 day2 内容整理翻译。

技术参考javascript.info 灾难性回溯专题ReScue 工具regular-expressions.info ReDoS 防御指南

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容