正则表达式注入攻击详解
字数 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)),攻击者注入.*可匹配多条路由。 - 日志分析工具:若日志查询功能动态构建正则,攻击者可能通过注入泄露敏感信息。
通过严格限制动态正则的构建逻辑,可有效避免此类漏洞。