正则表达式注入攻击详解
字数 913 2025-11-26 01:14:19

正则表达式注入攻击详解

1. 问题描述
正则表达式注入(Regex Injection)是一种利用用户输入动态构建正则表达式时未充分过滤导致的漏洞。攻击者通过向正则表达式模式中插入特殊字符或结构,改变原有意向,可能导致正则表达式引擎陷入极端回溯(如ReDoS攻击)、信息泄露或绕过输入验证。此类漏洞常见于搜索、路由匹配、输入验证等功能中。

2. 漏洞原理

  • 动态构建正则表达式的风险:若应用将用户输入直接拼接到正则表达式中,例如 new RegExp("^" + userInput + "$"),攻击者可输入如 .* 等元字符,使模式匹配范围扩大。
  • ReDoS攻击机制:恶意输入可构造回溯灾难性模式(如 ^(a+)+$ 匹配 aaaaaaaaX),导致正则引擎指数级回溯,耗尽CPU资源。
  • 绕过验证:例如,若密码强度检查使用 new RegExp(userAllowedPattern),攻击者可能通过 )|.* 使表达式变为 ^(allowed)|.*$,从而接受任意密码。

3. 攻击示例
假设应用使用以下代码验证用户名(仅允许字母数字):

let userInput = "alice"; // 正常输入
let regex = new RegExp("^[a-zA-Z0-9]*$"); // 正确做法:静态模式
// 错误做法:动态拼接模式
let dangerousRegex = new RegExp("^" + userInput + "$"); 

攻击者输入 [a-zA-Z0-9]*.*,最终正则变为 ^[a-zA-Z0-9]*.*$,可匹配任意字符,绕过限制。

4. 防御措施

  • 避免动态拼接:优先使用静态定义的正则模式,或将用户输入作为匹配文本而非模式的一部分。
  • 严格过滤输入:若必须动态构建,应对用户输入进行转义(如将 .*+?^${}()|[]\ 等元字符转义为字面量)。
  • 使用超时机制:对正则匹配设置超时(如Node.js的 regexp-timeout 库),防止ReDoS。
  • 白名单验证:对输入内容先进行白名单过滤,再用于构建正则。

5. 进阶场景

  • 路由注入:如Express.js路由定义 app.get(new RegExp("/user/" + userPath)),攻击者注入 .* 可匹配多条路由。
  • 日志分析工具:若日志查询功能动态构建正则,攻击者可能通过注入泄露敏感信息。

通过严格限制动态正则的构建逻辑,可有效避免此类漏洞。

正则表达式注入攻击详解 1. 问题描述 正则表达式注入(Regex Injection)是一种利用用户输入动态构建正则表达式时未充分过滤导致的漏洞。攻击者通过向正则表达式模式中插入特殊字符或结构,改变原有意向,可能导致正则表达式引擎陷入极端回溯(如ReDoS攻击)、信息泄露或绕过输入验证。此类漏洞常见于搜索、路由匹配、输入验证等功能中。 2. 漏洞原理 动态构建正则表达式的风险 :若应用将用户输入直接拼接到正则表达式中,例如 new RegExp("^" + userInput + "$") ,攻击者可输入如 .* 等元字符,使模式匹配范围扩大。 ReDoS攻击机制 :恶意输入可构造回溯灾难性模式(如 ^(a+)+$ 匹配 aaaaaaaaX ),导致正则引擎指数级回溯,耗尽CPU资源。 绕过验证 :例如,若密码强度检查使用 new RegExp(userAllowedPattern) ,攻击者可能通过 )|.* 使表达式变为 ^(allowed)|.*$ ,从而接受任意密码。 3. 攻击示例 假设应用使用以下代码验证用户名(仅允许字母数字): 攻击者输入 [a-zA-Z0-9]*.* ,最终正则变为 ^[a-zA-Z0-9]*.*$ ,可匹配任意字符,绕过限制。 4. 防御措施 避免动态拼接 :优先使用静态定义的正则模式,或将用户输入作为匹配文本而非模式的一部分。 严格过滤输入 :若必须动态构建,应对用户输入进行转义(如将 .*+?^${}()|[]\ 等元字符转义为字面量)。 使用超时机制 :对正则匹配设置超时(如Node.js的 regexp-timeout 库),防止ReDoS。 白名单验证 :对输入内容先进行白名单过滤,再用于构建正则。 5. 进阶场景 路由注入 :如Express.js路由定义 app.get(new RegExp("/user/" + userPath)) ,攻击者注入 .* 可匹配多条路由。 日志分析工具 :若日志查询功能动态构建正则,攻击者可能通过注入泄露敏感信息。 通过严格限制动态正则的构建逻辑,可有效避免此类漏洞。