正则表达式拒绝服务(ReDoS)攻击详解
字数 976 2025-11-11 11:50:26

正则表达式拒绝服务(ReDoS)攻击详解

一、问题描述
正则表达式拒绝服务(ReDoS)是一种针对应用层服务的攻击,攻击者通过构造特定的输入字符串,触发正则表达式引擎的指数级回溯多项式级回溯,导致服务器CPU资源被耗尽,从而拒绝正常服务。此类漏洞常见于输入校验、URL路由、数据解析等场景。

二、根本原因:正则引擎的匹配机制

  1. 回溯机制

    • 正则引擎(如PCRE、JavaScript的RegExp)在匹配时,若遇到量词(如*+{m,n})或分支(如(a|b)),会尝试所有可能的路径直到匹配成功。
    • 当匹配失败时,引擎会回溯到上一个决策点重新尝试,此过程可能产生大量计算。
  2. 脆弱正则模式

    • 嵌套量词:如(a+)+b,对字符串"aaaa..."(无b)匹配时,会指数级增加回溯路径。
    • 重叠分支:如(a|aa)+c,输入"aaa..."会导致分支组合爆炸。

三、攻击示例分析
以正则表达式^(a+)+$为例,匹配输入"aaaaaaaaX"(末尾含非法字符):

  1. 外层(a+)匹配所有a,但因需匹配整个字符串,引擎会尝试调整内层a+的匹配长度。
  2. 由于无b,引擎会回溯测试所有可能的分割方式(如(a)(a)(a)...(aa)(a)(a)...),导致时间复杂度从O(n) 变为O(2^n)

四、检测与防御方案

  1. 避免危险模式

    • 禁止嵌套量词(如(a+)+)或递归结构。
    • 使用非贪婪匹配(*?+?)减少回溯。
  2. 使用静态分析工具

    • 工具如regexplint(Python)或safe-regex(JavaScript)可检测潜在ReDoS模式。
  3. 限制匹配时间

    • 设置正则超时(如Python的regex模块的timeout参数)。
    • 对用户输入强制长度限制。
  4. 替换方案

    • 复杂校验改用确定性有限自动机(DFA)引擎或字符串处理函数。

五、实战场景

  • URL路由攻击:若路由规则使用脆弱正则(如/(a+)+/index),攻击者可通过恶意路径耗尽服务器资源。
  • 表单校验:邮箱正则^([a-zA-Z0-9]+\s?)+$可能被长字符串触发ReDoS。

通过理解回溯机制并严格约束正则编写,可有效规避ReDoS风险。

正则表达式拒绝服务(ReDoS)攻击详解 一、问题描述 正则表达式拒绝服务(ReDoS)是一种针对应用层服务的攻击,攻击者通过构造特定的输入字符串,触发正则表达式引擎的 指数级回溯 或 多项式级回溯 ,导致服务器CPU资源被耗尽,从而拒绝正常服务。此类漏洞常见于输入校验、URL路由、数据解析等场景。 二、根本原因:正则引擎的匹配机制 回溯机制 : 正则引擎(如PCRE、JavaScript的RegExp)在匹配时,若遇到量词(如 * 、 + 、 {m,n} )或分支(如 (a|b) ),会尝试所有可能的路径直到匹配成功。 当匹配失败时,引擎会 回溯 到上一个决策点重新尝试,此过程可能产生大量计算。 脆弱正则模式 : 嵌套量词 :如 (a+)+b ,对字符串 "aaaa..." (无 b )匹配时,会指数级增加回溯路径。 重叠分支 :如 (a|aa)+c ,输入 "aaa..." 会导致分支组合爆炸。 三、攻击示例分析 以正则表达式 ^(a+)+$ 为例,匹配输入 "aaaaaaaaX" (末尾含非法字符): 外层 (a+) 匹配所有 a ,但因需匹配整个字符串,引擎会尝试调整内层 a+ 的匹配长度。 由于无 b ,引擎会回溯测试所有可能的分割方式(如 (a)(a)(a)... 、 (aa)(a)(a)... ),导致时间复杂度从 O(n) 变为 O(2^n) 。 四、检测与防御方案 避免危险模式 : 禁止嵌套量词(如 (a+)+ )或递归结构。 使用非贪婪匹配( *? 、 +? )减少回溯。 使用静态分析工具 : 工具如 regexplint (Python)或 safe-regex (JavaScript)可检测潜在ReDoS模式。 限制匹配时间 : 设置正则超时(如Python的 regex 模块的 timeout 参数)。 对用户输入强制长度限制。 替换方案 : 复杂校验改用确定性有限自动机(DFA)引擎或字符串处理函数。 五、实战场景 URL路由攻击 :若路由规则使用脆弱正则(如 /(a+)+/index ),攻击者可通过恶意路径耗尽服务器资源。 表单校验 :邮箱正则 ^([a-zA-Z0-9]+\s?)+$ 可能被长字符串触发ReDoS。 通过理解回溯机制并严格约束正则编写,可有效规避ReDoS风险。