对于每个“邪恶”的正则表达式,是否存在非邪恶的替代项,还是语法中的恶魔?


16

显然,ReDos攻击利用了某些(其他有用的)正则表达式的特征...本质上导致了通过NFA定义的图的可能路径的爆炸式增长。

通过编写等效的“非邪恶”正则表达式可以避免此类问题吗?如果不是这样(因此,NFA无法在实际的空间/时间中处理语法),哪种解析方法会更好?为什么?


如果我设法使用精确的技术语言,那是偶然的。如果您是非学术人士,请把您的答案
David Bullock

1
我实际上只是在试图找到一种避免被ReDos'd攻击实用方法,这个问题浮出水面
大卫·布洛克

改写您的问题(?):每一种常规语言是否都有一个正则表达式,其长度由其最小NFA的状态数限制的多项式?
A.Schulz 2015年

1
@舒尔茨 我不认为这是问题。这不是ReDos攻击的工作原理。在ReDos攻击中,正则表达式被硬编码到程序源代码中,并由假定为受信任的开发人员提供。然后,对手开始提供输入字符串,程序将其与正则表达式进行匹配。如果对手可以找到一个使匹配器运行很长时间的输入字符串,那么对手将获胜。因此,我们关注的是对抗性输入,而不是对抗性正则表达式。(续)
DW

因此,我认为问题是:每种正则语言是否都有一个正则表达式,使得将字符字符串与该正则表达式进行匹配需要O f n 时间,其中f n 不太n的快速增长函数(例如,多项式或类似的东西)?[顺便说一下,这种重新表述清楚地表明,答案将取决于用于匹配的算法...正如我在答案中提到的。]正则表达式的大小与最小NFA大小的函数无关这里真的很重要。ñO(f(n))f(n)ñ
DW

Answers:


14

这取决于您是否拥有正则表达式或正则表达式:正则表达式是邪恶的,但是正则表达式是美的事物,永远不会对您不利。

regexp是指现代正则表达式:即具有附加现代功能(例如反向引用)的正则表达式-例如,与Perl兼容的正则表达式。这比形式语言/自动机理论教科书中的经典正则表达式更强大,因为经典正则表达式不允许反向引用,超前,向后看等等。

对于经典的正则表达式,如果您对匹配器具有良好的实现,则没有任何正则表达式太邪恶了。特别地,用于匹配的标准算法是将正则表达式转换为NFA,然后在输入字符串上执行NFA。对于此算法,当正则表达式固定时,测试字符字符串的最坏情况下的运行时间为O n 。这意味着运行时间不会爆炸得太快。没有字符串会导致运行时间成指数增长。因此,如果您使用的是使用此算法的匹配器,那么任何经典的正则表达式都不会有害。nO(n

这确实取决于正则表达式匹配器的实现。如果您对匹配器的执行过于幼稚或执行不力,那么匹配可能会花费指数时间。当然有具有该特性的算法。但是,最好的答案可能是不更改正则表达式。如果您担心拒绝服务攻击,最好选择一个更好的匹配器。

相比之下,某些现代正则表达式不可避免地是邪恶的。如果您有现代的正则表达式,则匹配可能需要指数时间。特别是,带有反向引用的正则表达式可以识别NP硬语言。因此,在合理的假设下,存在一类邪恶的正则表达式,其中测试匹配项需要花费指数时间。因此,一些现代的正则表达式不可避免地是邪恶的:没有可行的方法来找到一个等效的正则表达式,该正则表达式不会在运行时间中引起指数爆炸。

(这样的等效项可能存在,甚至可能在理论上是可以找到的,但是在合理的假设下,找到等效的正则表达式将花费指数时间,这在实践中不可行。如果您有系统的过程可以在多项式时间内找到等效的正则表达式, ,那么您可以在多项式时间内解决NP难题,证明P = NP。如果在您的生命周期内无法真正找到它,那么存在一个等效的正则表达式就没有多大好处。)


背景和来源:


通过将正则表达式拆分为多个较小的正则表达式并结合使用,找到一个非邪恶的替代方案是否更容易?
inf3rno

1

该答案将更全面地了解这种不寻常的交叉情况,在这种情况下,复杂性理论适用于网络安全,并且该示例包含了该领域可能出现的一些细微差别/微妙之处。这本质上类似于“注入攻击”,其中某些意外的输入会导致系统崩溃或导致系统花费异常长时间的病理行为。

维基百科具有15种拒绝服务攻击类别,该攻击属于该列表中的“应用程序级别洪水”。另一个类似的例子是充满应用程序日志的攻击。

解决注入攻击的一种方法是“清理输入”。应用程序设计者可以重新评估是否有必要编译由潜在恶意用户提供的任意正则表达式。仅仅去除regexp中的嵌套表达式或其他类似的限制就可能足以避免这种攻击。尽管它们是许多现代软件所固有的,但可以提供大量功能而无需评估正则表达式。上下文很重要,某些应用程序将不需要这种安全性。

此处适用的另一种提高容错/弹性的方法是在软件堆栈/层次结构的不同级别指定超时。想法是在“平均”正则表达式评估中指定时间/ cpu或指令限制,如果超过则提前终止。可以使用自定义解决方案来实现它们,但是为此目的,没有太多的软件或编程语言具有内置的超时或框架。

这是使用超时来提高容错能力的一个很好的示例,并显示了一个高级设计/体系结构/观点来缓解此类问题:高容量,分布式系统 / Netflix中的容错能力。它没有与正则表达式专门相关的任何东西,但这就是重点:几乎任何/所有应用程序级逻辑都可以适合此框架或类似的东西。

本文指出特别是回溯如何导致正则表达式匹配缓慢。正则表达式具有许多不同的功能,可以尝试评估哪些导致最坏情况的行为。

这是对这个特定主题的不错的科学调查,并提出了静态分析解决方案:

  • 通过子结构逻辑对正则表达式指数运行时进行静态分析 / Rathnayake,Thielecke

    使用回溯的正则表达式匹配可能具有指数运行时间,从而导致系统安全性文献中称为REDoS的算法复杂性攻击。在本文中,我们以最近发布的静态分析为基础,该分析可检测给定的正则表达式对于某些输入是否可以具有指数运行时间。通过形成过渡关系的幂和乘积,从而将REDoS问题减少到可及性,我们系统地构建了更准确的分析。使用搜索树的子结构演算来证明分析的正确性,其中导致指数爆炸的树分支被表征为非线性形式。


这个答案似乎对ReDos的某些方面感到困惑。1. ReDoS与注入攻击无关。注入攻击(例如XSS,SQL注入,命令注入等)完全不同。2. ReDos与对手提交的恶意正则表达式无关。通常,将regexp硬编码在程序中(由开发人员提供),输入字符串由用户提供。输入验证无法合理地解决该问题,因为通常没有明确的输入验证策略足以解决该问题。
DW

认为根据ReDos参考文献,您的观点等于技术性/不切实际,并错过了森林。它类似于 “精心设计的注射攻击”。答案指出,在代码中使用正则表达式还有其他选择。静态分析可以找到“邪恶的正则表达式”。答案的所有要点都是有效的。诸如“通常在程序中将正则表达式硬编码(由开发人员提供),输入字符串由用户提供”之类的句子与ReDos撰写不完全匹配,ReDos撰写在某些地方比较模糊,并且确实是指恶意攻击者等。
VZN
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.