正则表达式拒绝服务(ReDoS)攻击详解
字数 976 2025-11-11 11:50:26
正则表达式拒绝服务(ReDoS)攻击详解
一、问题描述
正则表达式拒绝服务(ReDoS)是一种针对应用层服务的攻击,攻击者通过构造特定的输入字符串,触发正则表达式引擎的指数级回溯或多项式级回溯,导致服务器CPU资源被耗尽,从而拒绝正常服务。此类漏洞常见于输入校验、URL路由、数据解析等场景。
二、根本原因:正则引擎的匹配机制
-
回溯机制:
- 正则引擎(如PCRE、JavaScript的RegExp)在匹配时,若遇到量词(如
*、+、{m,n})或分支(如(a|b)),会尝试所有可能的路径直到匹配成功。 - 当匹配失败时,引擎会回溯到上一个决策点重新尝试,此过程可能产生大量计算。
- 正则引擎(如PCRE、JavaScript的RegExp)在匹配时,若遇到量词(如
-
脆弱正则模式:
- 嵌套量词:如
(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参数)。 - 对用户输入强制长度限制。
- 设置正则超时(如Python的
-
替换方案:
- 复杂校验改用确定性有限自动机(DFA)引擎或字符串处理函数。
五、实战场景
- URL路由攻击:若路由规则使用脆弱正则(如
/(a+)+/index),攻击者可通过恶意路径耗尽服务器资源。 - 表单校验:邮箱正则
^([a-zA-Z0-9]+\s?)+$可能被长字符串触发ReDoS。
通过理解回溯机制并严格约束正则编写,可有效规避ReDoS风险。