三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

fastjson CVE-2026-16723 漏洞排查实战:Spring Boot fat-JAR 与 shaded 依赖的检测方法

fastjson CVE-2026-16723 漏洞排查实战:Spring Boot fat-JAR 与 shaded 依赖的检测方法

⚠️ 2026-08-04 重要更正:官方补丁已经发布了

本文最初写于 2026-08-03,文中「官方不会发布补丁、1.x 已停止维护」的说法是错的,在此更正。

阿里已于 2026-07-29 发布 fastjson 1.2.84,修复了 CVE-2026-16723。

之所以几乎没人知道,是因为这是一次静默发布—— 1.2.83 的 release 标题标注了「(安全修复)」,而 1.2.84 只写「1.2.84版本发布」,全文未提安全,所以安全媒体和扫描器都没跟进。

可自行核验:

  • Maven 中央仓库 https://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.84/ ,jar 上传时间 2026-07-29
  • GitHub release https://github.com/alibaba/fastjson/releases/tag/1.2.84 ,发布于 2026-07-29T08:24:51Z
  • 关键提交:fix: strengthen autoType type name validation and whitelist verification

对你的实际影响:升级到 1.2.84 是同分支小版本升级,通常无需改代码,不必被迫立刻做 fastjson2 的大版本迁移。

详细说明另见新文:fastjson 1.2.84 修复了吗?CVE-2026-16723 官方补丁核实与排查方法


先给结论

如果你只有 3 分钟,直接看这段:

  1. 影响范围:fastjson 1.2.68 ~ 1.2.83,CVSS 9.0,默认配置即可远程代码执行,不需要开 AutoType。
  2. 官方已出补丁:1.2.84(2026-07-29 静默发布,详见文首更正)。升个小版本通常就够,不必被迫做 fastjson2 大版本迁移。
  3. mvn dependency:tree查不全。两种情况漏检:①手上只有打好的 fat-JAR,没有构建环境;②fastjson 被 shade 进了某个 SDK 内部,依赖树上根本没这个节点。
  4. 迁到 fastjson2 也不一定安全:fastjson2 ≤ 2.0.62 自身有 RCE,安全版本是 2.0.63+。
  5. 快速自查命令(离线,不联网,不上传任何数据):
java-jarfastjson-check.jar ./myapp.jarjava-jarfastjson-check.jar /opt/apps

下面展开说为什么依赖树查不全,以及这两种漏检情况具体长什么样。


2026 年 7 月 21 日,fastjson 公布了 CVE-2026-16723:CVSS 9.0,远程代码执行,默认配置即可利用——不需要开启 AutoType,不需要 classpath 上有特定 gadget,不需要认证。

影响范围是 fastjson1.2.68 ~ 1.2.83

这次和以往几次 AutoType 系列漏洞有个本质区别:

官方不会发布补丁。fastjson 1.x 已经停止维护,GitHub 仓库已归档。

⚠️ 上述说法已过时:阿里已于 2026-07-29 发布fastjson 1.2.84修复本漏洞。因为是静默发布(release 标题未提安全),当时全网都还在说「无补丁」。

也就是说不存在"升个小版本就完事"这条路。要么迁移,要么长期带病运行。

公告后数日就出现了在野利用,主要目标是Spring Boot fat-JAR部署。

真正的难点不是修,是"找"

如果你的pom.xml里明明白白写着 fastjson,那这篇文章对你没什么用——你已经知道自己中招了,直接去迁移就行。

问题在于:大多数团队的 pom.xml 里根本没有 fastjson。

fastjson 极少被主动引入,它几乎都是传递依赖——被各种 SDK 捎带进来的。国内生态里尤其严重:支付、短信、对象存储、消息推送、地图、各种开放平台的 Java SDK,很多都在内部用 fastjson 做 JSON 序列化。

于是就出现了一个尴尬局面:

你没装它,但你在用它。而你不知道。

两个mvn dependency:tree的盲区

排查的第一反应当然是跑依赖树:

mvn dependency:tree|grepfastjson

这在大部分情况下够用。但有两种情况它无能为力,而这两种恰恰是应急场景里最常见的。

盲区一:你手上只有一个打好的 fat-JAR

线上应急的典型场景:运维扔给你一个myapp.jar,没有源码,机器上没有 Maven,甚至没有网。

这时候dependency:tree是跑不了的——它需要构建环境和完整的 POM 依赖解析。

有人会说那就unzip出来看。可以,但 Spring Boot fat-JAR 的结构是BOOT-INF/lib/*.jar,里面几十上百个 jar,还可能有嵌套。手工翻一遍的成本很高,而且容易漏。

盲区二:fastjson 被 shade 进了别的 jar 内部

这个更隐蔽。

有些 SDK 为了避免版本冲突,会在打包时用maven-shade-plugin把 fastjson直接打进自己的 jar 里。结果就是:

  • 依赖树上完全没有fastjson 这个节点
  • 但目标 jar 内部实实在在有com/alibaba/fastjson/JSON.class
  • 这段代码会被正常加载、正常执行、正常受漏洞影响

我一开始也以为依赖树干净就等于没事。实际上依赖树干净只说明没有独立的 fastjson 依赖节点,不说明 classpath 上没有 fastjson 的字节码。

能被 JVM 加载的类,才是攻击面。依赖树只是它的一个不完整投影。

写了个工具专门查这两种情况

针对上面两个盲区写了个小工具,fastjson-check

# 扫一个 jar,Spring Boot fat-JAR 会自动逐层展开java-jarfastjson-check.jar ./myapp.jar# 扫一整个目录,递归找所有 jar/warjava-jarfastjson-check.jar /opt/apps# 输出 JSON,接流水线java-jarfastjson-check.jar /opt/apps--json

输出长这样:

fastjson-check 0.1.0 —— fastjson 应急排查(离线,不外传任何数据) 扫描目标:myapp.jar 已展开归档:3 个 发现 2 处 fastjson: [CRITICAL] fastjson 1.2.83 位置 :myapp.jar!/BOOT-INF/lib/fastjson-1.2.83.jar 版本来源:pom.properties 场景 :Spring Boot fat-JAR ← CVE-2026-16723 的主要在野利用场景 结论 :命中 CVE-2026-16723(CVSS 9.0 远程代码执行) 处置 :按成本从低到高:①(推荐)升级至 fastjson **1.2.84** —— 同分支小 版本升级,通常无需改代码;② 迁移至 fastjson2 2.0.63+;③ 无法升级时 先启用 SafeMode 彻底关闭 AutoType 缓解。 [UNKNOWN] fastjson 版本未知 位置 :myapp.jar!/BOOT-INF/lib/some-sdk-3.1.0.jar 版本来源:未知 注意 :疑似被 shade 进宿主 jar(有 class 但无 Maven 元数据), mvn dependency:tree 查不到它 结论 :无法确定 fastjson 版本 汇总:CRITICAL 1 UNKNOWN 1

注意第二条——那个some-sdk-3.1.0.jar把 fastjson 打进了自己内部,依赖树上完全看不见。这正是它存在的理由。

几个设计上的取舍:

  • 零运行时依赖。一个排查工具不该再往目标环境里塞任何东西,尤其不该塞 JSON 库——我们查的就是它。全程只用 JDK 自带的java.util.zip
  • 编译目标 Java 8。企业环境里大量 JRE 还是 8,打出来的 jar 要能直接丢到老机器上跑。
  • 完全离线。不联网、不上传任何数据。排查生产环境的包,把路径和依赖清单发到第三方服务器上是不可接受的。
  • 内存内展开嵌套 jar。不往磁盘落任何临时文件。
  • 整个 jar23KB

一个容易踩的坑:迁到 fastjson2 ≠ 安全

官方给的迁移方向是 fastjson2。但要注意:

fastjson2 在 ≤ 2.0.62 时自身也有 RCE(多态反序列化,seeAlso 路径,同样是默认配置可触发)。

所以「我们已经迁到 fastjson2 了」这句话本身不构成安全结论,必须同时看版本号。安全版本是2.0.63 及以上

完整判定规则:

版本判定说明
fastjson1.2.68 ~ 1.2.83🔴 CRITICAL命中 CVE-2026-16723,升级至 1.2.84 即修复
fastjson≥ 1.2.84🟢 OK已包含 CVE-2026-16723 的官方修复
fastjson 1.x 其他版本🟠 HIGH不中本次 CVE,但有历史 AutoType RCE 系列漏洞
fastjson2≤ 2.0.62🔴 CRITICAL多态反序列化 RCE,默认配置即可触发
fastjson2≥ 2.0.63🟢 OK当前推荐版本

接 CI

退出码设计成可以直接做门禁:

  • 0= 未发现需处理项
  • 1= 发现 CRITICAL/HIGH
  • 2= 用法错误
java-jarfastjson-check.jar ./build/libs||echo"发现高危依赖,阻断发布"

它不是什么

诚实说明边界,免得误以为安全:

  • 它不是通用 SCA 工具。只查 fastjson 一个库,不查其他 CVE。要全面的依赖安全扫描请用 Snyk / OWASP Dependency-Check / Dependency-Track。
  • 改了包名的 relocate 打包检测不到。它靠com/alibaba/fastjson(2)/JSON.class这个路径识别;如果某个库在 shade 时把包名 relocate 成了com.foo.shaded.fastjson,就查不出来。
  • 它不判断可达性。发现依赖存在 ≠ 一定能被攻击,是否真的可利用取决于有没有外部可控的 JSON 输入路径。但在应急阶段,先把「有没有」查清楚是第一步。
  • 它不改你的代码。只报告,不动手。

获取方式

工具是我写的,Apache 2.0 开源,已用 Maven 中央仓库的真实fastjson 1.2.62 / 1.2.83 和 fastjson2 2.0.62 / 2.0.63 验证过,26 个单元测试。

下载(23KB,单个 jar,零依赖,Java 8+ 可跑):

https://github.com/xiaoqiMikko/fastjson-check/releases

如果打不开 GitHub,命令行直接拉:

curl-LOhttps://github.com/xiaoqiMikko/fastjson-check/releases/download/v0.1.0/fastjson-check.jar

用法

java-jarfastjson-check.jar<jar文件或目录>java-jarfastjson-check.jar<目标>--json# JSON 输出,接流水线java-jarfastjson-check.jar<目标>--utf8# Windows 控制台中文乱码时加这个

退出码0未发现需处理项 /1发现 CRITICAL 或 HIGH /2用法错误,可直接做 CI 门禁。

源码:https://github.com/xiaoqiMikko/fastjson-check

发现误报或漏报,请在 GitHub 提 issue。安全工具最怕的就是让人误以为安全,任何一条误判我都想知道。

← 返回列表