ReDoS代表正则表达式拒绝服务。 ReDoS是一种算法复杂性攻击,它通过提供需要很长时间才能评估的正则表达式来产生拒绝服务的攻击。该攻击利用了以下事实:大多数正则表达式实现都有指数时间(最坏情况下)的复杂性,因此对于较大的输入字符串(“邪恶的正则表达式”),正则表达式引擎查找匹配项所花费的时间呈指数增长。
攻击者的目的是提供这样的正则表达式,以使其花费不确定的计算时间,从而使应用程序变慢或完全瘫痪。
因此,这种攻击基本上利用了正则表达式引擎将尝试所有可能的字符排列和组合以找到匹配项这一事实。
可以在整个Web上找到正则表达式,并且可以使用ReDoS攻击来针对Web的各个组件。
ReDOS攻击的样本表达
正则表达式: ^((ab)*)+ $(此正则表达式搜索ab及其重复)
输入: ababab
在这种情况下,由于ababab匹配正则表达式模式,因此正则表达式引擎将在第一次尝试中找到匹配项。现在,我们可以通过输入abababa作为输入很容易地使事情复杂化。最终,这个exta a会引起各种各样的麻烦,因为它与模式不匹配,并且会使正则表达式引擎运行各种排列以寻找可能的匹配。
(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])+ $作为用户名和aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!作为密码,程序将挂起。
预防:
- 在您的正则表达式中使用原子分组。原子组是一个组,当正则表达式引擎退出该组时,它会自动丢弃该组内所有标记记住的所有回溯位置
- 如果正则表达式花费的时间太长,请立即将其杀死,并通知用户正则表达式花费的时间太长。
- 预格式化/验证正则表达式或让人们直接搜索文本,而不是直接输入正则表达式。
参考:
- 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/ Main_Page的