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

SonarQube S5852安全热点:split方法正则回溯DoS问题解决方案

java:S5852正则DoS安全热点规避方案

java:S5852是SonarQube用于检测存在灾难性回溯风险正则的规则,这类正则在处理恶意构造的长输入时,会因回溯机制导致CPU占用飙升,最终触发拒绝服务。
你当前使用的正则(\\s*°\\s*)|(\\s*'{1,2}\\s*)风险点非常明确:两个匹配分支都以贪婪模式的\\s*开头,当输入存在连续长段空白、且后续没有命中°或单引号分隔符时,正则引擎会在两个分支之间反复回退重试,匹配耗时会随输入长度呈多项式级增长。

方案1:彻底弃用正则,手动实现拆分逻辑(最推荐)

你的拆分规则非常固定,完全没必要用正则实现。手动按字符遍历拆分的逻辑是线性时间复杂度,从根源上消灭ReDoS风险,性能也比正则高很多,逻辑和原有实现完全等价。
直接替换原有split调用即可:

private String[] splitLatStr(String input) {
    List<String> segments = new ArrayList<>();
    StringBuilder cur = new StringBuilder();
    int idx = 0, len = input.length();
    while (idx < len) {
        char c = input.charAt(idx);
        // 跳过所有空白字符,自动过滤分隔符前后的空格
        if (Character.isWhitespace(c)) {
            idx++;
            continue;
        }
        // 匹配°分隔符
        if (c == '°') {
            segments.add(cur.toString().trim());
            cur.setLength(0);
            idx++;
            continue;
        }
        // 匹配单引号/双单引号分隔符,优先匹配更长的''分隔符避免歧义
        if (c == '\'') {
            idx += (idx + 1 < len && input.charAt(idx + 1) == '\'') ? 2 : 1;
            segments.add(cur.toString().trim());
            cur.setLength(0);
            continue;
        }
        cur.append(c);
        idx++;
    }
    if (cur.length() > 0) {
        segments.add(cur.toString().trim());
    }
    return segments.toArray(new String[0]);
}

// 业务代码替换原有split调用
String[] latData = splitLatStr(expPoint.getLatDegree());
if (latData.length == 4) {
    point.setLatitudeDegree(Integer.valueOf(latData[0]));
    point.setLatitudeMinute(Integer.valueOf(latData[1]));
    point.setLatitudeSecond(Double.valueOf(latData[2]));
    point.setLatitudeQuad("N".equals(latData[3]));
}

这个实现可以正确处理分隔符前后任意数量的空白,也能准确区分'和''两种分隔符,和你原有正则的拆分结果完全一致,不存在行为差异。

方案2:优化正则结构,消除回溯路径

如果不想新增工具方法,也可以通过调整正则写法直接规避S5852检测,核心是切断正则的回溯路径:

// 优化后正则,无回溯风险
String splitRegex = "\\s*+(?:°|'{2}|')\\s*+";
String[] latData = expPoint.getLatDegree().split(splitRegex);

优化点说明:

  • 把原来分散在两个分支的\\s*前缀提取到公共位置,避免分支间因为匹配重叠内容产生回溯
  • 空白匹配使用所有格量词\\s*+,匹配到的空白字符不会被引擎回退,从根源上消除贪婪匹配带来的回溯风险
  • 分隔符按最长优先顺序排列(先匹配''再匹配'),避免匹配歧义

如果采用正则方案,建议额外加一层输入长度校验:合法的经纬度度分秒字符串长度通常不会超过30字符,超长输入直接判定为非法拦截,进一步降低风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:24:27