一条命令,查清你的 Java 应用里到底有没有 fastjson、藏在哪、是否受 CVE-2026-16723 影响。
零依赖 · 完全离线 · 单个 23KB 的 jar · 支持 Java 8+
2026 年 7 月 21 日,fastjson 官方公布 CVE-2026-16723(CVSS 9.0,远程代码执行):
大量安全通告(含多家英文安全媒体)至今仍称「1.x 已 EOL、永远不会有补丁、只能迁移到 fastjson2」。 该说法自 2026-07-29 起已不成立。 可自行核验:
| 证据 | 链接 |
|---|---|
Maven 中央仓库有 com.alibaba:fastjson:1.2.84,jar 上传于 2026-07-29 | repo1 |
GitHub release 1.2.84,发布于 2026-07-29T08:24:51Z | release |
关键提交 fix: strengthen autoType type name validation and whitelist verification | 2026-07-29T07:02:55Z |
1.2.83 发布于 2022 年 5 月,此后 1.x 分支四年无提交 —— 1.2.84 是为本次漏洞专门破例发布的。
它的 release 标题没有标注安全修复:1.2.83 的标题写了「(安全修复)」,而 1.2.84 只写
「1.2.84版本发布」。但正文是写了的 —— 有完整的 Security Fixes 章节,逐条列出四项 AutoType
加固,且从发布当天(2026-07-29)起就是这样(Wayback 存档 20260729094935 可查)。
至于为什么补丁发布后安全通告与扫描器大多仍未跟进,我没有查清,这里不做猜测。
📌 2026-08-14 更正:此处原写「全文未提安全,因此没有被跟进」。前半句经 release 正文与 Wayback 当天存档实测为错(只有标题未标注),后半句因此也失去依据,一并删去。
👉 对 1.x 用户的实际影响:升级到 1.2.84 是成本最低的处置(同分支小版本,通常无需改代码), 不必被迫立刻做 fastjson2 的大版本迁移。本工具已按此给出建议。
⚠️ 前提是 JDK 8 及以上(2026-10-14 实测):1.2.84 的 274 个 class 全是 Java 8 字节码(major 52), 1.2.83 是 Java 5(major 49)。在 JDK 7(Zulu 7u352)上
javac只给警告、退出码 0,运行时直接抛UnsupportedClassVersionError: com/alibaba/fastjson/JSON : Unsupported major.minor version 52.0。 另:1.2.84 里的JSON.VERSION常量仍是"1.2.83",按它判版本会看错;本工具读的是pom.properties,不受影响。
而最麻烦的一点是:
fastjson 通常是传递依赖 —— 没人主动装它,它是被别的库捎带进来的。 很多团队根本不知道自己在用它。
mvn dependency:tree 能列出依赖,但对两种情况无能为力:
本工具就是为这两种情况写的。
从 Releases 下载 fastjson-check.jar,然后:
# 扫一个 jar(Spring Boot fat-JAR 会自动逐层展开)
java -jar fastjson-check.jar ./myapp.jar
# 扫一整个目录(递归查找所有 jar/war)
java -jar fastjson-check.jar /opt/apps
# 输出 JSON,接入流水线
java -jar fastjson-check.jar /opt/apps --json
不需要安装、不需要账号、不联网、不上传任何数据。
同一个构件既是 CLI 也是 Maven 插件。这种用法不需要先下载 jar:
# 在你的项目目录下直接跑,扫的是 Maven 解析后的依赖
mvn io.github.xiaoqimikko:fastjson-check:0.3.1:check
或者绑进构建生命周期(verify 阶段):
<plugin>
<groupId>io.github.xiaoqimikko</groupId>
<artifactId>fastjson-check</artifactId>
<version>0.3.1</version>
<executions>
<execution>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
pom.xml 更准CLI 扫 pom.xml 时读到的是文本,而真实项目里 fastjson 的版本常常不在那段文本里:
<version>${fastjson.version}</version><parent>,你自己的 pom 里没有这一行插件拿到的是 Maven 解析完成之后的依赖集合,每个依赖都带着本地仓库里的真实 jar 路径。
于是走的正是本工具最擅长的那条路:扫真 jar 里的 com/alibaba/fastjson(2)/JSON.class,
而不是相信 pom 上写了什么。
⚠️ 但识别边界没有因此改变:判定键仍然是那个 class 路径,所以 被 relocate / 改包名重打包的依赖依然识别不出来(见下方「它不是什么」)。 插件解决的是「版本写在哪」,不是「包名被改了」。
| 参数 | 默认 | 说明 |
|---|---|---|
-Dfastjson-check.failOnFound | false | 发现 CRITICAL / HIGH 时让构建失败 |
-Dfastjson-check.path | 不设 | 不扫依赖树,改扫这个路径(目录 / jar / war / fat-jar) |
-Dfastjson-check.skip | false | 跳过执行 |
🔴 默认不让构建失败,这是刻意的,和 CLI 的退出码语义不同:
命令行是你自己敲的,退出码 1 正是你要的;而插件是挂在流水线上的,
一个自查工具不该在你毫无准备的时候把构建打红。要当 CI 门禁,显式加
-Dfastjson-check.failOnFound=true。
💡 Windows 上如果报告是乱码,把控制台切回 GBK(
chcp 936)—— 插件模式的输出编码由 Maven 决定,CLI 的--utf8/--gbk开关在这里够不着。
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 远程代码执行),默认配置即可利用
处置 :1.x 已停止维护,不会有修复版本。应急处置二选一:①(推荐)迁移至
fastjson2 2.0.63 或更高版本;② 无法立即迁移时,先启用 SafeMode
彻底关闭 AutoType 以缓解,但这不是长期方案。
[UNKNOWN] fastjson 版本未知
位置 :myapp.jar!/BOOT-INF/lib/some-sdk-3.1.0.jar
版本来源:未知
场景 :Spring Boot fat-JAR ← CVE-2026-16723 的主要在野利用场景
注意 :疑似被 shade 进宿主 jar(有 class 但无 Maven 元数据),mvn dependency:tree 查不到它
结论 :无法确定 fastjson 版本
汇总:CRITICAL 1 UNKNOWN 1
注意第二条 —— 那个 some-sdk-3.1.0.jar 把 fastjson 打包进了自己内部,依赖树上完全看不见。
| 版本 | 判定 | 说明 |
|---|---|---|
| fastjson 1.2.68 ~ 1.2.83 | 🔴 CRITICAL | 命中 CVE-2026-16723,升 1.2.84 即可修复 |
| fastjson ≥ 1.2.84 | 🟢 OK | 已含官方修复(2026-07-29 发布) |
| fastjson < 1.2.68 | 🟠 HIGH | 不中本次 CVE,但有历史 AutoType RCE 系列漏洞 |
| fastjson2 ≤ 2.0.62 | 🔴 CRITICAL | 多态反序列化 RCE(seeAlso 路径),默认配置即可触发 |
| fastjson2 ≥ 2.0.63 | 🟢 OK | 当前推荐版本 |
⚠️ 特别注意:官方推荐的迁移目标 fastjson2 自身在 ≤2.0.62 时也有 RCE。 「已经迁到 fastjson2」不等于安全,必须同时看版本号。
--json 输出 JSON,便于接入流水线(恒为 UTF-8)
--utf8 强制以 UTF-8 输出(控制台中文乱码时用)
--gbk 强制以 GBK 输出(控制台中文乱码时用)
--no-color 关闭彩色输出
-h, --help 显示帮助
-v, --version 显示版本
退出码:0 = 未发现需处理项(且每个文件都真的读进去了);1 = 发现 CRITICAL/HIGH;2 = 用法错误;4 = 有文件读不动(见文末「退出码」一节)。
可直接用于 CI 门禁:
java -jar fastjson-check.jar ./build/libs --json || echo "发现高危依赖,阻断发布"
诚实说明边界,免得误以为安全:
com/alibaba/fastjson(2)/JSON.class 这个路径识别;如果某个库在 shade 时把包名改成了 com.foo.shaded.fastjson,就查不出来mvn clean package
# 产物:target/fastjson-check.jar
编译目标为 Java 8,因此打出来的 jar 可以直接丢到还在跑 JRE 8 的老机器上执行。 运行时零依赖 —— 一个排查工具不该再往目标环境里塞任何东西(尤其不该塞 JSON 库,我们查的就是它)。
发现误报或漏报,请开一个 Issue。 安全工具最怕的就是让人误以为安全,任何一条误判都值得提。
提 issue 时如果能附上这些信息,定位会快很多:
java -jar fastjson-check.jar <目标> --json 的输出(JSON 里不含任何路径以外的敏感信息)功能建议、新的 fastjson 相关 CVE、企业批量排查场景的需求,同样欢迎开 issue 讨论。
这个工具回答的是「我中没中」。下面这些它答不了,可以找我做:
📮 [email protected] —— 说清情况,我 24 小时内给你一页书面答复: 能不能做、难在哪、大概多久。这一步免费,也不用你先承诺什么。
Apache License 2.0
One command to find out whether your Java application ships fastjson, where it hides, and whether you are exposed to CVE-2026-16723.
Zero dependencies · fully offline · a single 22KB jar · Java 8+
On 2026-07-21 a remote code execution flaw in fastjson was disclosed as CVE-2026-16723 (CVSS 9.0):
Most advisories — including major security outlets — still state that fastjson 1.x is EOL, that no patch will ever ship, and that migrating to fastjson2 is the only option. That has been untrue since 2026-07-29. Verify it yourself: