fastjson 2.0.63 安全更新:加固 AutoType,修复 OOM 与 DoS 解析风险

2026-07-30 33 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

fastjson 2.0.63 是一次应优先处理的安全更新。该版本强化了 AutoType 反序列化校验,同时修复了多个可由构造输入触发的解析健壮性问题,包括内存耗尽(OOM)和拒绝服务(DoS)风险。

如果应用会接收外部 JSON 或 JSONB 数据,例如开放 API、消息队列事件、文件导入和跨系统 RPC,就不应把这次升级当成普通依赖维护。攻击者不一定需要绕过业务鉴权,只要能够让服务解析特制输入,就可能消耗大量内存或计算资源。

这次更新影响哪些应用

需要重点排查的不是“项目是否直接调用 fastjson2”,而是“不可信数据是否最终进入 fastjson2 解析器”。常见入口包括:

  • HTTP 请求体、Webhook 和开放平台回调
  • Kafka、RocketMQ 等消息系统中的事件载荷
  • 用户上传的 JSON 或 JSONB 文件
  • 缓存、数据库字段中保存的序列化对象
  • 网关、RPC 框架或第三方 SDK 间接引入的 fastjson2
  • 开启或依赖 AutoType 的多态反序列化流程

AutoType 允许解析器根据输入中的类型信息恢复具体 Java 类型。它能简化多态对象处理,但也扩大了输入对运行时类型选择的影响。因此,只要数据来源不完全可信,就需要对类型白名单、可实例化类和反序列化入口保持严格控制。

OOM 与 DoS 风险则不一定依赖 AutoType。恶意输入可能利用异常长度、深度、容器结构或特定编码组合迫使解析器分配大量内存,或长时间占用 CPU。升级和资源边界控制需要同时进行,不能只依赖某一个开关。

直接升级到 2.0.63

Maven 项目可以将 fastjson2 版本显式更新为 2.0.63:

<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.63</version>
</dependency>

Gradle 项目对应配置如下:

dependencies {
    implementation("com.alibaba.fastjson2:fastjson2:2.0.63")
}

修改后,应检查最终解析出来的依赖版本,避免父 POM、BOM 或传递依赖仍然锁定旧版本:

# Maven
mvn dependency:tree -Dincludes=com.alibaba.fastjson2

# Gradle
./gradlew dependencyInsight \
  --dependency fastjson2 \
  --configuration runtimeClasspath

对于多模块仓库,建议在 dependency management 或版本目录中集中固定版本,而不是逐个模块修改。这样可以减少同一进程中出现多个 fastjson2 版本的概率。

暂时不能升级时启用安全模式

如果受发布窗口、兼容性验证或上游框架限制而无法立即升级,可以通过 JVM 系统属性启用解析器安全模式,以缓解 AutoType 相关问题:

java \
  -Dfastjson2.parser.safeMode=true \
  -jar app.jar

在 Kubernetes 中,可以通过 JAVA_TOOL_OPTIONS 注入该参数:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  template:
    spec:
      containers:
        - name: order-service
          image: example/order-service:1.8.0
          env:
            - name: JAVA_TOOL_OPTIONS
              value: "-Dfastjson2.parser.safeMode=true"

部署后可检查进程参数,确认配置确实进入运行中的 JVM:

kubectl exec deploy/order-service -- \
  sh -c 'jcmd 1 VM.system_properties | grep fastjson2.parser.safeMode'

需要明确的是,安全模式是无法立即升级时的临时缓解措施,重点针对 AutoType 风险。它不能替代 2.0.63 中的完整解析健壮性修复,也不应被视为 OOM 或 DoS 问题的统一解决方案。启用后还要回归测试依赖多态反序列化的功能,因为更严格的类型处理可能改变原有行为。

给解析入口增加资源边界

依赖升级之外,应用还应限制攻击者能够提交的数据规模。下面是一个可以改造的 Spring Boot 示例,在进入 fastjson2 前检查请求体大小,并避免直接反序列化为由客户端决定的任意类型:

package example.api;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;

@RestController
public class ImportController {
    private static final int MAX_JSON_BYTES = 1024 * 1024;

    public record ImportRequest(String orderId, int quantity) {}

    @PostMapping("/imports")
    public ResponseEntity<?> importData(@RequestBody byte[] body) {
        if (body.length > MAX_JSON_BYTES) {
            return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE)
                    .body("JSON payload exceeds 1 MiB");
        }

        try {
            ImportRequest request = JSON.parseObject(
                    new String(body, StandardCharsets.UTF_8),
                    ImportRequest.class
            );
            return ResponseEntity.ok(request);
        } catch (JSONException ex) {
            return ResponseEntity.badRequest().body("Invalid JSON payload");
        }
    }
}

这个示例中的 1 MiB 只是实践假设,实际值应根据业务数据分布设定。网关、Servlet 容器和应用层最好同时配置限制,避免超大请求在抵达业务代码前就占用过多连接、缓冲区或堆内存。

对于 JSONB、消息队列和文件导入,也应采用相同思路:限制单条消息或文件大小,设置消费超时和并发上限,并将解析失败视为不可重试或有限重试事件,避免同一恶意载荷形成重试风暴。

升级验证清单

升级不应只验证“服务能启动”。更有效的检查包括:

  • 确认生产运行时实际加载的是 fastjson2 2.0.63
  • 回归 JSON 与 JSONB 的正常序列化、反序列化流程
  • 测试多态对象、历史数据和启用 AutoType 的兼容场景
  • 对超大、截断、深度嵌套和类型异常输入执行负向测试
  • 观察解析失败率、CPU、堆内存、GC 暂停和容器重启次数
  • 检查网关、消息系统和文件上传入口是否设置大小限制
  • 清理不再需要的 AutoType 配置和宽泛类型许可

fastjson 2.0.63 的核心价值不只是修复某一个反序列化条件,而是同时收紧类型校验并提升解析器面对恶意输入时的稳定性。最稳妥的处理顺序是尽快升级、验证最终依赖版本,再为所有不可信数据入口补上大小、类型、超时和并发边界。安全模式可以争取修复时间,但不应成为长期停留在旧版本上的理由。


相关推荐