Fastjson 1.2.83「无 Gadget」RCE 研究深度解析与企业防护建议

Fastjson 1.2.83 曾被视为 1.x 系列中「autoType 相关问题的最终答卷」,但近期公开的「gadget-free / 无 Gadget」RCE 研究再次把它推回聚光灯下。本文用 10 分钟把这类研究背后的原理、影响面与企业侧应对策略讲清楚——不给 PoC,只给能落地的行动清单。

一、背景:Fastjson 1.2.83 究竟修了什么

Fastjson 是国内最广泛使用的 JSON 解析库之一,1.x 版本从 1.2.24 起长期与「autoType 反序列化」问题共存。1.2.83(2022 年 8 月发布)是 1.x 系列最后一次针对 autoType 的重大加固,主要动作包括:

  • 扩展 autoType 内置黑名单,覆盖历史上出现过的 JNDI、JDBC、模板引擎、RMI 相关类前缀;
  • 加强 checkAutoType 的类名混淆识别(大小写、L/;、内部类分隔符 $ 等常见绕过技法);
  • 推荐启用 safeMode:从根本上禁用 autoType,只允许字段声明的静态类型。

换句话说,1.2.83 的官方态度是:如果你还在用 1.x,请开 safeMode;如果不能开 safeMode,请尽快迁移到 Fastjson2。

二、什么叫「无 Gadget(gadget-free)」RCE

传统的 Java 反序列化 RCE 依赖一条「Gadget 链」:攻击者用一系列已存在于 classpath 中的「有副作用的方法调用」串起来,最终触发命令执行(经典如 CommonsCollectionsGroovyROME 链)。1.2.83 的黑名单就是围绕这些历史链条构建的。

「无 Gadget」并不字面等于「不依赖任何第三方类」,而是指不依赖一条历史已知的、可被签名识别的 Gadget 链。它把攻击面从「哪条链没被封」转向:

  • Fastjson 反序列化过程中被动触发的语义原语(getter/setter 调用、构造器副作用、代理类回调);
  • expectClassautoTypeSupport 交互时的「白名单信任漏斗」;
  • JDK 与常见框架里天然存在的、不出现在任何 CommonsCollections 类型链中的类——资源加载、类加载、代理注入等语义。
研究者的核心思路:不去和黑名单硬碰硬,而是找到 Fastjson「必须信任」的一小类语义(例如 expectClass 强制类型的调用路径),并把攻击载荷伪装成该语义的合法输入。

三、影响面判断:谁真正需要担心

并不是所有 1.2.83 部署都同样危险。按风险从高到低排序:

  1. 高危:暴露在互联网上的 API 网关 / 业务接口,直接把用户请求体交给 JSON.parseObject(String) 或带宽松特性(如 Feature.SupportNonPublicField)的解析,且未开启 safeMode
  2. 中危:内部系统之间的 JSON 通信(含 MQ、RPC 桥接)使用 1.2.83、未开 safeMode,但网络访问受 ACL 限制;
  3. 较低:只用作序列化输出、或只解析强类型 POJO,且已启用 safeMode=true
  4. 基本无关:已迁移至 Fastjson2(com.alibaba.fastjson2)2.0.x 及以上,默认不启用 autoType。

四、检测:怎么排查你到底在用哪个版本

企业内部通常同时存在多种依赖来源,建议按顺序做 4 步排查:

  1. 依赖清点:对所有 Java 服务跑 mvn dependency:tree / gradle dependencies,抓取 com.alibaba:fastjson 的实际解析版本;
  2. 运行时验证:在测试环境读取 com.alibaba.fastjson.JSON 所在 JAR 的 Implementation-Version,防止被间接引入但 dependency:tree 中不显示;
  3. 安全配置盘点:检查启动参数 / 环境变量是否存在 -Dfastjson.parser.safeMode=true,或代码里 ParserConfig.getGlobalInstance().setSafeMode(true)
  4. 入口审计:搜索 JSON.parseparseObjectparseArray 的所有调用点,标记哪些直接接收外部输入。

五、企业级修复方案(按优先级)

P0(本周完成):把攻击面「关掉一半」

  • 为所有 1.2.83 运行的 Java 服务,强制开启 safeMode=true——这一步不需要改业务代码,通过启动参数即可,是官方对 1.x 用户的核心建议;
  • 如果业务确实需要 autoType,改用显式的 ParserConfig.getGlobalInstance().addAccept("你的包前缀.") 白名单,把 autoType 收敛到已知业务类型;
  • 在 WAF / API 网关加一条通用规则:对 application/json 请求体,拒绝或告警顶层出现 "@type" 键(业务真正需要多态时,改由服务端映射,而非客户端指定)。

P1(本季度完成):迁移到 Fastjson2

Fastjson2 是官方替代实现,包名改为 com.alibaba.fastjson2,默认关闭 autoType,并引入更严格的类型解析器。迁移建议:

  • 先引入 fastjson2-extension 兼容层,逐个 API 灰度切换,保留 1.x 依赖直到验证完成;
  • 关注 parseObject(String, TypeReference) 的行为差异,重点检查历史上依赖 @type 做多态反序列化的业务点;
  • 迁移后强制启用 Fastjson2 的 JSONReader.Feature.SupportAutoType 白名单机制,永远不打开全局 autoType。

P2(本半年完成):构建纵深防御

  • 网络层:出站访问控制。所有生产服务器默认禁止对外发起 LDAP/RMI/DNS 直连——这是 JNDI 类攻击兑现「二段载荷」的必经之路,切断即失效;
  • 运行时层:部署 Java RASP(可考虑开源方案如 OpenRASP,或商用产品),对 ClassLoader.defineClassScriptEngine.evalRuntime.exec 打钩子;
  • 数据层:分析历史 6 个月的 "@type" 出现频次,评估业务真正需要多态反序列化的接口占比——多数团队会发现「其实一个都不需要」。

六、常见误区澄清

  1. 误区一:只要装了 WAF 就没事。WAF 只能挡「特征已知」的载荷,而 gadget-free 类研究天然规避这一类特征,纵深防御不可省。
  2. 误区二:内网就绝对安全。反序列化漏洞常见于内部 RPC、MQ 消息桥、数据同步组件,一旦某个环节被穿透,攻击面很快穿透到生产核心。
  3. 误区三:升级到 1.2.83 就是终点。1.2.83 是止损版本,不是「终态方案」——终态是 Fastjson2 + safeMode + 最小 autoType 白名单。
  4. 误区四:开 safeMode 会导致业务大规模报错。实际项目里 90% 以上的解析路径都不依赖 autoType,可先在灰度环境跑一周,观察 autoTypeSupport is disabled 报错分布,再针对性开白名单。
Halocent 视角:从 100+ 客户资产盘点里,我们发现真正开着 safeMode 的 Fastjson 1.x 部署不到 25%。这个数字意味着:只要花一天时间打一次开关,中国企业整体的 Java RCE 攻击面能立刻下降一大截。

七、行动清单(可直接抄)

  1. 本周内:全量清点 Java 服务的 Fastjson 版本 + safeMode 开关状态;
  2. 本周内:把 -Dfastjson.parser.safeMode=true 加进所有 1.x 服务的启动模板;
  3. 2 周内:在 WAF 出一条阻断 "@type" 顶层出现的规则,全面启用 audit 模式先观察 7 天;
  4. 1 个月内:在生产网络禁止对外发起 LDAP / RMI / 未经审批的高危出站;
  5. 本季度:完成 Fastjson2 的迁移计划、里程碑、责任人;
  6. 本半年:完成 RASP / EDR 组合、以及一次「Java 反序列化」专题攻防演练。

如果你希望把这份清单落到自己的资产上,Halocent 光晕科技可以基于我们的自动化扫描工具,为你出一份「Fastjson 全量暴露面 + 修复优先级」报告——通常需要 3–5 个工作日。

← 返回行业资讯

需要一份「Fastjson 暴露面盘点报告」吗?

1 个工作日内响应,3–5 个工作日交付:从版本、safeMode 状态、外部接口暴露面、修复优先级一次讲清。