ReDoS代表正则表达式拒绝服务。 ReDoS 是一种算法复杂性攻击,它通过提供需要很长时间来评估的正则表达式来产生拒绝服务。该攻击利用了大多数正则表达式实现具有指数时间最坏情况复杂性这一事实,因此对于较大的输入字符串(“邪恶的正则表达式”),正则表达式引擎查找匹配项所花费的时间呈指数增长。
攻击者的目标是提供这样的正则表达式,以便它需要无限量的计算时间,这反过来会减慢应用程序或完全降低它的速度。
因此,这种攻击基本上利用了正则表达式引擎将尝试所有可能的字符排列和组合以找到匹配项的事实。
正则表达式可以在整个网络中找到,ReDoS 攻击可用于针对网络的各种组件。
ReDOS 攻击的示例表达式
正则表达式: ^((ab)*)+$(此正则表达式搜索 ab 及其重复)
输入: ababab
在这种情况下,正则表达式引擎将在第一次尝试中找到匹配项,因为 ababab 匹配正则表达式模式。现在我们可以很容易地通过将 abababa 作为输入来使事情复杂化。这个 exta 最终会导致各种麻烦,因为它与模式不匹配,并且会使正则表达式引擎运行各种排列以寻找可能的匹配。
(ababab) - NOT A MATCH
(abab)(ab) - NOT A MATCH
(ab)(abab) - NOT A MATCH
(ab)(ab)(ab) - NOT A MATCH
()(ababab) - NOT A MATCH
()(abab)(ab) - NOT A MATCH
()(ab)(abab) - NOT A MATCH
()(ab)(ab)(ab) - NOT A MATCH
您可以在此在线正则表达式编辑器中亲自试用。现在想象一下,如果输入更长一些
abababababababababababababababababababababababababab......
它会造成什么样的破坏。
邪恶的正则表达式
它们是使应用程序容易受到 ReDoS 攻击的正则表达式,只要发生以下因素,它们就会发生:
- 正则表达式将重复(“+”、“*”)应用于复杂的子表达式
- 对于重复的子表达式,存在一个匹配,它也是另一个有效匹配的后缀。
恶意正则表达式的示例包括:
- (a+)+
- ([a-zA-Z]+)*
- (a|aa)+
- (a|a?)+
- (.*a){x} 对于 x > 10
通过 Evil Regex 攻击 Web 应用程序:
- 打开 JavaScript 并找到 Evil Regex
- 为找到的 Regex 制作恶意输入并通过拦截代理提交有效值
- 将请求更改为包含恶意输入,您就可以进行 ReDos 攻击了
通过正则表达式注入的 ReDoS
以下示例检查用户名是否是用户输入的密码的一部分。
String userName = textBox1.Text;
String password = textBox2.Text;
Regex testPassword = new Regex(userName);
Match match = testPassword.Match(password);
if (match.Success)
{
MessageBox.Show("Do not include name in password.");
}
else
{
MessageBox.Show("Good password.");
}
如果攻击者输入^(([az])+.)+[AZ]([az])+$作为用户名并且aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa作为密码,程序将挂起。
预防:
- 在正则表达式中使用原子分组。原子组是这样一个组,当正则表达式引擎退出时,它会自动丢弃组内任何标记记住的所有回溯位置
- 如果正则表达式耗时太长,立即终止它,并通知用户正则表达式耗时太长。
- 预先格式化/验证您的正则表达式或让人们直接搜索文本,而不是直接输入正则表达式。
参考:
- https://www.linkedin.com/pulse/redos-attacks-python-application-architectures-akshat-mahajan
- http://stackoverflow.com/questions/12841970/how-can-i-recognize-an-evil-regex
- https://www.owasp.org/index. PHP/Regular_expression_Denial_of_Service_-_ReDoS
- 图片来源:https://www.owasp.org/index。 PHP/主页面