这个正则表达式容易受到REDOS攻击吗

时间:2019-10-11 16:21:39

标签: regex regex-dos-attack

正则表达式:

  

^\d+(\.\d+)*$

我试图用打破它:

  

1234567890.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 .1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 .1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 .1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 .1.1.1x]

即200x“ .1”

我从以下位置了解了有关ReDos攻击的信息:

但是,我对自己的技巧不太自信,无法对表达式进行ReDos攻击。由于“嵌套量词”,我试图触发灾难性的回溯。

该表达是否容易破解?应该使用什么输入?如果是,您是如何提出的?

2 个答案:

答案 0 :(得分:6)

“嵌套量词”本质上不是问题。这只是引用一个实际上更复杂的问题的简单方法。问题是“对子表达式进行量化,该子表达式本身可以以多种方式在同一位置进行匹配”。事实证明,您几乎总是需要在内部子表达式中提供一个量词,以提供足够丰富的匹配项,因此,量词中的量词充当指示故障的可能性的危险信号。

(.*)*是有问题的,因为.*具有最大的对称性-它可以在输入的任何点匹配零到所有其余字符之间的任何字符。重复此操作会导致组合爆炸。

([0-9a-f]+\d+)*是有问题的,因为在数字串中的任何点处,都有许多可能的方法可以在[0-9a-f]+的初始子串和\d+的最终子串之间分配这些数字。 ,因此它与(.*)*的问题完全相同。

(\.\d+)*是没有问题的,因为\.\d匹配完全不同的事物。一个数字不是一个点,一个点不是一个数字。在输入的任何给定点上,只有一种可能的方式来匹配\.,并且只有一种可能的方式来匹配\d+,这使得再次重复的可能性成为可能(消耗所有数字,因为如果我们会在数字前停下,下一个字符肯定不是点)。因此,(\.\d+)*在相同的上下文中也不会比\d*更糟,即使它包含嵌套的量词。

答案 1 :(得分:3)

您的正则表达式是安全的,但仅出于“ \。”

在regex101.com上进行的测试表明,没有输入组合会产生失控的检查-但是您的正则表达式非常容易受到攻击,因此在进行修改时要小心。

如您所读,当两个量词紧挨着时,发生灾难性的回溯。就您而言,正则表达式将扩展为\d+\.\d+\.\d+\.\d+\. ...,依此类推。因为您在\d+之间的每个匹配项中都加上了点,所以正则表达式对于您添加的每个周期号仅增长三步。 (如果在末尾放置无效字符,则每个句号数将转换为4步。)这是线性增长率,因此您的正则表达式很好。 Demo

但是,如果您将\.设置为可选,则偶然忘记了转义字符以使其与.保持一致,或者将其完全删除,然后然后< / em>您遇到了麻烦。这样的正则表达式将导致灾难性的回溯。末尾的无效字符会使您添加的每个其他数字使运行时间加倍。这是一个指数级的增长率,足以使regex101引擎的默认设置(仅18位数字和1个无效字符)超时。 Demo

按照书面规定,您的正则表达式可以使用,只要您确保第一个\d+和第二个\d+之间有“固定”,并且保持“固定”就可以了在捕获组之外的第二个\d+*之间。