跳转至

正则表达式 (Regular Expression)

正则表达式拒绝服务攻击 (ReDoS) 是一种攻击类型,它利用某些正则表达式处理时间极长这一特性,导致应用程序或服务无响应或崩溃。

摘要 (Summary)

工具 (Tools)

  • tjenkinson/redos-detector - 一个 CLI 工具和库,可以确定正则表达式模式是否能免受 ReDoS 攻击。支持在浏览器、Node 和 Deno 中运行。
  • doyensec/regexploit - 查找易受 ReDoS(正则表达式拒绝服务)攻击的正则表达式。
  • devina.io/redos-checker - 检查正则表达式中潜在的拒绝服务漏洞。

方法论 (Methodology)

邪恶正则 (Evil Regex)

邪恶正则通常包含:

  • 带有重复的分组
  • 在重复的分组内部包含:
    • 重复
    • 带有重叠的选择 (Alternation)

示例

  • (a+)+
  • ([a-zA-Z]+)*
  • (a|aa)+
  • (a|a?)+
  • (.*a){x} 其中 x > 10

这些正则表达式可以使用 aaaaaaaaaaaaaaaaaaaa! (20 个 'a' 后跟一个 '!') 来进行攻击。

aaaaaaaaaaaaaaaaaaaa! 

对于此输入,正则引擎会尝试所有可能的分组方式来匹配 a 字符,直到最后意识到因为 ! 的存在匹配失败。这会导致回溯尝试的次数爆炸式增长。

回溯限制 (Backtrack Limit)

正则表达式中的回溯发生在正则引擎尝试匹配模式但遇到不匹配时。引擎随后会回溯到上一个匹配位置,并尝试另一条替代路径来寻找匹配。这个过程可能会重复多次,在使用复杂模式和处理大型输入字符串时尤为明显。

PHP PCRE 配置选项

名称 默认值 备注
pcre.backtrack_limit 1000000 对于 PHP < 5.3.7 为 100000
pcre.recursion_limit 100000 /
pcre.jit 1 /

有时可以强制正则表达式超过 100,000 次递归,这将导致 ReDoS 并使 preg_match 返回 false

$pattern = '/(a+)+$/';
$subject = str_repeat('a', 1000) . 'b';

if (preg_match($pattern, $subject)) {
    echo "发现匹配";
} else {
    echo "未发现匹配";
}

参考资料 (References)