You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SonarQube告警正则存在灾难性回溯风险是否需要重写

结论

这个正则存在明确的灾难性回溯风险,不是SonarLint误报,必须重写。

风险原因拆解

你写的正则RegExp('^(?!(.|\n)*{/?.+})(.|\n)*$')核心逻辑是校验整段文本内不存在{xxx}、{/xxx}这类闭合的模板标签片段,触发回溯的问题点有两个:

  • (.|\n)是典型的高危写法:这个分组的两个分支匹配范围完全不互斥——.匹配除换行符外的所有字符,\n单独匹配换行,当后续匹配失败需要回溯时,每一个字符位置都会产生两种匹配路径的分支,指数级拉高计算量。
  • 负向预查内的(.|\n)*和后续的.+都是贪婪匹配,且匹配范围高度重叠:当输入构造的特殊字符串(比如开头为{,后续全为普通字母、没有闭合}的长文本)时,正则引擎会反复回退尝试所有可能的字符拆分组合,输入长度只要到几十位就能产生上万次回溯,长度到千位级别时会直接卡住JS单线程,触发正则拒绝服务(ReDoS)。
安全的替代实现

完全不需要写复杂的全量匹配负向预查,反过来做违规内容检测即可,逻辑等价、零回溯风险,性能比原正则高几个数量级:

// 校验逻辑:字符串中不存在 {任意内容} 或 {/任意内容} 的闭合标签
function isTextValid(str) {
  // 这个正则是线性扫描,[^}]+ 明确匹配非}的所有字符,无重叠匹配空间,不会产生回溯
  return !/\{\/?[^}]+\}/.test(str);
}

如果必须写成整串匹配的正则形式(比如适配某些表单校验规则的要求),可以用无回溯的写法,开启dotAll模式避免冗余分组:

// 等价逻辑,无回溯风险,s标志让.可以匹配换行符
const safeReg = /^(?!.*\{\/?[^}]+\}).*$/s;
避坑提示
  • 不要用(.|\n)、(.|\s)这类带重叠分支的分组匹配任意字符,需要匹配包含换行的全量字符时,优先用正则的s(dotAll)标志,兼容旧环境时用[\s\S]字符组实现,字符组不会产生分支回溯。
  • 避免相邻使用匹配范围重叠的贪婪量词,比如不要写.*.+这类结构,给匹配内容加上明确的边界(比如匹配{}包裹的内容时,中间用[^}]+而不是.+),从根源上掐断回溯的可能。
  • 校验「不存在某类片段」的需求时,优先用「检测到违规片段直接返回false」的正向判断思路,比写嵌套负向预查更不容易写出ReDoS漏洞。

内容的提问来源于stack exchange,提问作者S0ul3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:31:15