正则表达式拒绝服务(ReDoS)漏洞与防护
字数 989 2025-11-20 10:16:44
正则表达式拒绝服务(ReDoS)漏洞与防护
描述
正则表达式拒绝服务(ReDoS)是一种安全漏洞,攻击者通过提供特定模式的输入,使正则表达式引擎陷入极端耗时的回溯过程,导致服务资源耗尽,形成拒绝服务。该漏洞源于正则表达式引擎的NFA(非确定性有限自动机)实现机制,当模式书写不当时,对恶意输入可能产生指数级的时间复杂度。
解题过程
-
理解正则表达式引擎的工作原理
- 正则表达式引擎通常采用NFA(非确定性有限自动机),通过回溯机制尝试所有可能的匹配路径。
- 回溯发生在正则表达式中包含量词(如
*、+、{m,n})或可选分支(如|)时,当当前路径匹配失败,引擎会退回并尝试其他路径。
-
识别危险的正则模式
- 嵌套量词:如
(a+)+b,对输入"aaaa..."(无b)会尝试指数级次数的回溯。 - 重叠匹配:如
(a|aa)*b,输入"aaa..."会导致分支路径爆炸。 - 重复组与贪婪匹配:例如
^(a+)+$匹配字符串"aaaaaaaaX"时,每增加一个a,回溯次数翻倍。
- 嵌套量词:如
-
分析攻击场景
- 用户输入验证(如邮箱、URL校验)、日志分析、模板解析等场景中,若使用低效正则,攻击者可提交类似
"aaaaaaaaaaaaaaaaaaa!"的字符串触发ReDoS。 - 示例:正则
^(([a-z])+.)+[A-Z]([a-z])+$对输入"abcde"正常,但对"a"*20 + "!"会造成CPU占用飙升。
- 用户输入验证(如邮箱、URL校验)、日志分析、模板解析等场景中,若使用低效正则,攻击者可提交类似
-
防护措施
- 避免危险模式:
- 用具体字符类(如
\w+)替代模糊量词。 - 消除嵌套量词,例如将
(a+)+改为a+。
- 用具体字符类(如
- 使用非回溯或限制回溯的引擎:
- 部分引擎支持占有型量词(如
a++)或原子组((?>...)),禁止回溯。
- 部分引擎支持占有型量词(如
- 设置超时机制:
- 在代码中为正则匹配设置时间上限(如Python的
regex.set_timeout(0.5))。
- 在代码中为正则匹配设置时间上限(如Python的
- 采用静态分析工具:
- 使用工具(如SonarQube、CodeQL)检测代码中的危险正则模式。
- 替换非正则方案:
- 简单字符串操作(如
split()、indexOf())可替代部分正则场景,提升效率。
- 简单字符串操作(如
- 避免危险模式:
-
测试验证
- 使用ReDoS测试工具(如
regexploit)扫描代码库中的正则表达式。 - 对用户输入的正则匹配进行压力测试,提交长字符串验证响应时间是否线性增长。
- 使用ReDoS测试工具(如