fastjson 正则拒绝服务简单分析
字数 1528 2025-08-25 22:58:20

Fastjson 正则拒绝服务漏洞分析

漏洞概述

Fastjson 1.2.36至1.2.62版本中存在一个正则表达式拒绝服务(ReDoS)漏洞,攻击者可以通过构造特定的JSON数据,利用JSONPath功能中的正则表达式匹配机制,导致服务端CPU资源耗尽,形成拒绝服务攻击。

漏洞原理

正则表达式拒绝服务(ReDoS)基础

ReDoS(Regular Expression Denial of Service)是指攻击者构造特定的输入字符串,使得正则表达式引擎需要指数级的时间来匹配,从而导致系统资源耗尽。

示例代码展示了基本的ReDoS原理:

String p = "^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$";
String strPropertyValue = "aaaaaaaaaaaaaaaaaaaaaaaaaaaa!";
Pattern pattern = Pattern.compile(p);
Matcher m = pattern.matcher(strPropertyValue);
boolean match = m.matches();

这个正则表达式在处理特定输入时(如大量"a"字符后跟"!")会导致匹配时间急剧增加。

Fastjson中的JSONPath功能

Fastjson 1.2.0之后版本支持JSONPath功能,可以当作对象查询语言(OQL)使用。JSONPath支持两种模式匹配:

  1. [key like 'aa%'] - 字符串类型like过滤,支持通配符%
  2. [key rlike 'regexpr'] - 字符串类型正则匹配过滤,使用JDK正则语法

示例用法:

Object body = JSONPath.eval("{\"html\": {\"body\": \"bob\"}}", "$.html['body']");
System.out.println(body); // 输出: bob

漏洞触发路径

漏洞的核心在于Fastjson处理$ref引用时与JSONPath的结合使用:

  1. 当JSON解析遇到$ref键时,会调用JSONPath.eval()方法
  2. 如果$ref值包含rlike操作符,会创建RlikeSegement过滤器
  3. 该过滤器会使用用户提供的正则表达式进行匹配
  4. 恶意构造的正则表达式和输入字符串会导致ReDoS

漏洞利用分析

关键代码路径

  1. JSON解析入口

    Object parse = JSON.parse(json);
    

    这会初始化DefaultJSONParser并进行JSON对象转换

  2. 引用解析
    DefaultJSONParser#parseObject中,当遇到$ref键时会添加解析任务:

    if (key == "$ref" && ref != null && ref.length() > 0) {
        addResolveTask(task);
    }
    
  3. 解析任务处理
    DefaultJSONParser#handleResovleTask中调用JSONPath.eval

    if (ref.startsWith("$")) {
        refValue = getObject(ref);
        if (refValue == null) {
            try {
                refValue = JSONPath.eval(value, ref);
            } catch (JSONPathException ex) {
                // skip
            }
        }
    }
    
  4. 正则匹配执行
    JSONPath.eval()最终会调用RlikeSegement#apply方法执行正则匹配

漏洞利用Payload

构造特定的JSON数据可以触发此漏洞:

{
    "regex": {
        "$ref": "$[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']"
    },
    "blue": "aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"
}

这个Payload中:

  • $ref值包含rlike操作符和恶意正则表达式
  • blue字段提供了精心构造的输入字符串
  • 两者结合会导致正则匹配时间急剧增加

影响范围

  • 影响版本:Fastjson 1.2.36至1.2.62
  • 安全版本:1.2.63及以上

修复方案

  1. 升级Fastjson到1.2.63或更高版本
  2. 如果无法升级,可以禁用JSONPath功能或过滤包含rlike的输入

技术细节补充

RlikeSegement实现

RlikeSegementFilter接口的实现类,其apply方法负责执行正则匹配:

public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) {
    String propertyName = this.propertyName;
    Object propertyValue = path.getPropertyValue(item, propertyName, false);
    if (propertyValue == null) {
        return false;
    }
    String strValue = propertyValue.toString();
    Pattern pattern = Pattern.compile(this.pattern);
    boolean match = pattern.matcher(strValue).matches();
    return this.not ? !match : match;
}

调用链总结

完整的漏洞触发调用链:

JSON.parse()
→ DefaultJSONParser.parse()
→ DefaultJSONParser.parseObject() // 处理$ref
→ addResolveTask()
→ handleResovleTask()
→ JSONPath.eval()
→ FilterSegment.eval()
→ RlikeSegement.apply()
→ Pattern.matcher().matches()

防御建议

  1. 输入验证:对用户提供的正则表达式进行严格验证
  2. 超时机制:为正则匹配设置超时限制
  3. 资源限制:限制单个请求的CPU使用时间
  4. 功能禁用:如不需要JSONPath功能,可完全禁用

参考链接

Fastjson 正则拒绝服务漏洞分析 漏洞概述 Fastjson 1.2.36至1.2.62版本中存在一个正则表达式拒绝服务(ReDoS)漏洞,攻击者可以通过构造特定的JSON数据,利用JSONPath功能中的正则表达式匹配机制,导致服务端CPU资源耗尽,形成拒绝服务攻击。 漏洞原理 正则表达式拒绝服务(ReDoS)基础 ReDoS(Regular Expression Denial of Service)是指攻击者构造特定的输入字符串,使得正则表达式引擎需要指数级的时间来匹配,从而导致系统资源耗尽。 示例代码展示了基本的ReDoS原理: 这个正则表达式在处理特定输入时(如大量"a"字符后跟" !")会导致匹配时间急剧增加。 Fastjson中的JSONPath功能 Fastjson 1.2.0之后版本支持JSONPath功能,可以当作对象查询语言(OQL)使用。JSONPath支持两种模式匹配: [key like 'aa%'] - 字符串类型like过滤,支持通配符% [key rlike 'regexpr'] - 字符串类型正则匹配过滤,使用JDK正则语法 示例用法: 漏洞触发路径 漏洞的核心在于Fastjson处理 $ref 引用时与JSONPath的结合使用: 当JSON解析遇到 $ref 键时,会调用 JSONPath.eval() 方法 如果 $ref 值包含 rlike 操作符,会创建 RlikeSegement 过滤器 该过滤器会使用用户提供的正则表达式进行匹配 恶意构造的正则表达式和输入字符串会导致ReDoS 漏洞利用分析 关键代码路径 JSON解析入口 : 这会初始化 DefaultJSONParser 并进行JSON对象转换 引用解析 : 在 DefaultJSONParser#parseObject 中,当遇到 $ref 键时会添加解析任务: 解析任务处理 : 在 DefaultJSONParser#handleResovleTask 中调用 JSONPath.eval : 正则匹配执行 : JSONPath.eval() 最终会调用 RlikeSegement#apply 方法执行正则匹配 漏洞利用Payload 构造特定的JSON数据可以触发此漏洞: 这个Payload中: $ref 值包含 rlike 操作符和恶意正则表达式 blue 字段提供了精心构造的输入字符串 两者结合会导致正则匹配时间急剧增加 影响范围 影响版本:Fastjson 1.2.36至1.2.62 安全版本:1.2.63及以上 修复方案 升级Fastjson到1.2.63或更高版本 如果无法升级,可以禁用JSONPath功能或过滤包含 rlike 的输入 技术细节补充 RlikeSegement实现 RlikeSegement 是 Filter 接口的实现类,其 apply 方法负责执行正则匹配: 调用链总结 完整的漏洞触发调用链: 防御建议 输入验证 :对用户提供的正则表达式进行严格验证 超时机制 :为正则匹配设置超时限制 资源限制 :限制单个请求的CPU使用时间 功能禁用 :如不需要JSONPath功能,可完全禁用 参考链接 原始漏洞分析文章: fastjson 正则拒绝服务简单分析 Fastjson官方文档: https://github.com/alibaba/fastjson OWASP ReDoS指南: https://owasp.org/www-community/attacks/Regular_ expression_ Denial_ of_ Service_ -_ ReDoS