跳转到内容

防御 ReDoS 攻击

ReDoS (Regular expression Denial of Service) 正则表达式拒绝服务攻击。

攻击原理为: 服务端开发者使用正则表达式对用户输入数据进行校验,当正则表达式不严谨时, 攻击者可以构造特殊字符串以便大量消耗服务器资源,造成服务中断或停止。

当然,这也和正则表达式引擎有关。引擎分为 DFA(确定性有限状态自动机)和 NFA(非确定性有限状态自动机)。DFA 对于文本串里的每一个字符只需扫描一次,性能高,但特性较少。NFA 要回溯字符串,性能较低,但是特性(如:分组、替换、分割)丰富。同时支持惰性(lazy)、回溯(backtracking)、反向引用(backreference),NFA 缺省应用 greedy 模式,NFA可能会陷入递归险境导致性能极差。

所以在 NFA 才会出现 ReDoS 攻击。最优的方法是使用 DFA。

我们定义一个正则表达式^(a+)+$来对字符串 aaaaX 匹配。使用NFA的正则引擎,必须经历2^4=16次尝试失败后才能否定这个匹配。同理字符串为aaaaaaaaaaX就要经历2^10=1024次尝试。如果我们继续增加a的个数为20个、30个或者更多,那么这里的匹配会变成指数增长。

当然,我们可以利用 Regexploit 工具,该工具用于从代码中提取正则表达式,对其进行扫描并查找可能存在的 ReDoS 攻击。