由RegexProof (LX AI)
应用程序正则表达式的ReDoS启发式
ReDoS 在应用程序中的含义
正则表达式拒绝服务(ReDoS)发生在精心设计的输入强制匹配器进入灾难性的回溯时。CPU 突然飙升,请求延迟爆发,单个端点可能会使整个进程陷入饥饿状态。这不是理论上的琐事:任何在 HTTP 边界、日志行或上传名称中使用风险重复的正则表达式都是一个候选项。
我从 OWASP ReDoS 页面开始,然后将其映射到我们的路由(OWASP ReDoS)。启发式传递故意很枯燥:找到嵌套的量词、重叠的 alternation 和大输入字段中的模糊重复。
它首先发作的地方
- 公共表单上的电子邮件 / URL / “自由文本标签” 验证器 - 重用应用程序模式的 WAF 或网关规则 - 在每行上运行的日志编辑正则表达式 - LLM 生成的带有堆叠星号和加号的 “严格” 验证器
直观形状立即标记
嵌套量词,如(a+)+,(a*)*或(a+)*,是教科书中的形式。重叠的alternation,如(a|a)+,或更微妙的共享前缀,会产生相同的爆炸。可选组被外部重复包裹,很容易在审查中忽略,因为它们看起来很整洁。
还要标记将贪婪重复与经常失败的尾随条件混合的模式,因为引擎在拒绝之前会遍历巨大的树。如果您不能草拟出匹配为什么是线性的原因,请将其视为有罪,直到被证明是无罪的。
检查清单 —— 第一遍
- 任何同一组链上的量词内的量词 - 可以匹配相同前缀的alternation分支 - 在长字符串上,未绑定的.*或.+在失败的字面量之前 - 用户控制的输入长度在regex运行之前没有硬性限制
模式进入生产环境前的步骤工作流
- 在框架层限制输入长度,在正则表达式运行之前。 - 编写测试用例:短的正常路径,长的近似字符串和一些对抗性重复。 - 在生产引擎中运行模式,设置时间预算(如果超过几毫秒则测试失败)。 - 将嵌套重复重写为更清晰的有界形式,或者用解析器替换正则表达式以处理结构化数据。 - 当必须保留复杂模式时,记录残余风险,包括所有者和审查日期。
RegexProof 在解释伪造时会指出风险重复,这是第一次通行,不是对所有输入的安全性证明。
作为控制的引擎选择
一些部署将热门验证器移到设计为避免灾难性回溯的引擎(RE2风格的保证)。这是一个架构控制,而不是正则表达式的调整。如果您仍然使用回溯引擎,例如典型的ECMAScript RegExp或PCRE,您需要负责模式审查。阅读您实际运行的方言:ECMA-262 RegExp用于JavaScript,PCRE用于许多网关。
控制 | 它带来的好处 | 它不带来的好处 输入长度限制 | 限制最坏情况下的工作量 | 模式的正确性 嵌套+/*的启发式lint | 捕获常见的模式 | 新颖的慢速模式 计时单元测试 | CI中的回归信号 | 对所有对手的证明 非回溯引擎 | 删除了一整类风险 | 与PCRE玩具的功能相符 人类对LLM输出的审查 | 早期停止堆叠量词 | 完美的保证
常见错误
- 假设“这只是验证”所以ReDoS不适用 - 复制一个严格的电子邮件正则表达式,具有嵌套重复,因为它感觉很彻底 - 在无边界的请求体上运行正则表达式 - 相信生成器的解释而不进行计时测试 - 在销售文案中声称“我们永远不会错过ReDoS”——这夸大了其作用
决策标准:重写、重新定位或保留
当模式可以被读作一个小的状态机或字符串库调用时,重写。当需要丰富的匹配但可以将其移到请求线程外并设置严格的超时时,重新定位。仅当测试数据在长时间的近似匹配输入中保持快速,并且所有者接受残留风险时,才保留。
什么这不是
我如何在不欺骗自己的情况下为测试用例设置时间
仅使用短小的快乐路径字符串的ReDoS审查总是看起来很好。我保持一个近似输入的文件夹:模式喜欢的重复字符的长运行,然后是一个失败的预告片。如果匹配超过CI运行器上的小毫秒预算,测试将失败。
如果团队无法就预算达成一致,请从保守的上限开始,一旦有基准,就可以收紧。重点是回归信号,而不是科学论文。将计时测试与输入长度限制配对,以便生产环境永远不会看到大规模的玩具。
示例审查问题
- 我们允许的最长输入长度是多少,之后正则表达式就会运行? - 哪个组将量词嵌套在另一个量词内? - 两个分支是否可以消耗相同的前缀? - 是否有任何日志编辑作业在无限制的行上重用此模式? - 如果下个月计时失败,谁拥有重写的所有权?
用无聊的代码替换正则表达式
许多“聪明”的验证器以split/join、URL解析器或小手动解析器的形式更为清晰。 无聊的代码具有线性行为,你可以读懂。 当模式开始收集星号时,我将结构化格式(UUID、具有固定形状的日期、简单令牌)从正则表达式中移除。
正则表达式仍然适用于轻量级词法分析。 诚实规则很简单:如果你无法解释最坏情况下的增长,请不要将其放在请求路径上。
LLM辅助锻造的操作员笔记
像堆叠量词这样的模型看起来很精确。除非启发式检查清单和计时固定装置通过,否则将每个锻造视为不受信任的。RegexProof的边缘情况调用是一个起始过滤器。您的CI预算和输入上限是保持网站运行的控制器。
编写状态更新时,请说明您测量的内容(固定装置时间,输入上限),而不是声称具有完全保护。夸大其词会在下一个新颖模式出现时创建支持债务。
字段笔记:在不夸大其词的情况下进行交付
我拒绝使用那种说法一个工具永远不会错过方言漏洞或ReDoS形状的状态语言。老实说,我们在生产引擎中运行测试用例,我们限制输入长度,并且我们审查嵌套量词。残余风险仍然由一个特定的人承担。
这种立场使博客文章与RegexProof实际销售的内容保持一致——一个带有解释和边缘情况标志的forge——而不是一个神话般的完美扫描器。需要正式保证的读者仍然需要他们自己的安全审查。
当你教一个初级团队成员时,让他们故意用一个长的近似字符串来破坏一个模式。看着CPU升高的教训比另一个抽象的警告更有效。然后修复模式,并在CI中保留失败的测试用例,以便教训深入人心。
结束
在缓慢的测试用例后关闭循环
当一个有时间限制的测试用例失败时,我不会首先增加时间限制。我会重写嵌套的重复,添加输入限制,或者将检查移到请求路径之外。在没有重写的情况下增加时间限制会教导系统接受缓慢的模式。
在票据中写下测试用例之前和之后的时间,以便下一个审查者看到改进。将对抗字符串保持在CI中永远。这一个习惯可以防止在有人稍后简化模式而不重新运行长时间用例时发生安静的回归。
将对抗测试用例放在模式文件旁边,以便审查者永远不必寻找它们。
参考资料
- OWASP ReDoS - ECMA-262 RegExp - PCRE
尝试产品:RegexProof
2026-09-16 · 仅主来源 · 不含虚假流量指标
相关阅读
- ecmascript 与 pcre 方言陷阱 2026 - LX AI 微 SaaS 主题矩阵
什么是RegexProof?
RegexProof将自然语言描述转换为您选择的引擎的正则表达式,然后逐部分解释并标记边缘情况。
RegexProof支持哪些正则表达式风格?
您可以选择风格——ECMAScript/JavaScript、PCRE和其他——并应将其验证为生产方言,而不仅仅是粘贴测试器。
RegexProof如何减少ReDoS风险?
它解释了重复和替换,并调用了容易发生灾难性回溯的模式,这是ReDoS(正则表达式拒绝服务)的根本原因。同时,RegexProof还遵守PCRE和ECMAScript的相关标准。
RegexProof是否免费?
免费层包括每月10个forge;Pro是每月19美元,用于更高的容量。
为什么ECMAScript和PCRE表现不同?
回顾支持、Unicode模式和递归模式在引擎之间有所不同,因此PCRE中的有效模式可能会在JavaScript中失败或表现不同。
仅供决策参考。不作为正式验证或完整性保证。