Ruby环境中该正则表达式是否安全?是否存在回溯风险?
Ruby正则
%r{(.*)/(.*)}的极端输入风险分析 结论:这个正则存在回溯风险,无法抵御极端输入
为什么会产生回溯?
这个正则使用了两个贪婪模式的.*,匹配逻辑如下:
- 第一个
.*会先尝试匹配整个输入字符串 - 当发现后续没有
/可以匹配时,会逐步回溯(每次回退一个字符),直到找到/的位置 - 如果输入是超长且不含
/的字符串(比如连续一万个a),正则引擎会执行上万次回溯操作才能确定匹配失败,直接拖慢程序甚至引发崩溃,这就是典型的ReDoS(正则表达式拒绝服务)风险
常规场景没问题,但极端场景会翻车
你测试的aaaaaaaaaaaaaaa/aaaaaaaaaaaaaaa这类带单个/的输入确实不会有明显问题,因为第一个.*只需回溯几次就能找到/。但遇到以下极端输入时,风险会直接暴露:
- 超长无
/字符串:比如连续10000个a - 恶意构造的多
/超长字符串:虽然后者回溯次数少于无/场景,但仍可能引发性能瓶颈
优化方案
根据你的实际需求选择更安全的写法:
- 若需按**第一个
/**分割字符串,使用非贪婪匹配:%r{(.*?)/(.*)},第一个.*?碰到第一个/就停止匹配,避免不必要的回溯 - 若确定左侧内容不含
/,使用精准匹配:%r{([^/]*)/(.*)},[^/]*仅匹配非/的字符,完全不会产生回溯,性能和安全性拉满
内容的提问来源于stack exchange,提问作者Sim
相关产品推荐
相关产品推荐

