在当今的互联网世界中,Java 作为一门成熟、稳定且功能强大的编程语言,被广泛应用于企业级系统、分布式架构和微服务开发。然而,在享受其高效与便捷的同时,开发者也必须直面一个长期存在的高危安全风险——Java 反序列化漏洞。

这个看似不起眼的技术细节,曾引发过席卷全球的安全风暴,影响包括 WebLogic、WebSphere、JBoss 等在内的几乎所有主流中间件。本文将带你从零开始,深入剖析 Java 反序列化漏洞的底层原理、攻击手法、真实案例以及防护策略,助你构建更安全的应用系统。
什么是序列化与反序列化?
要理解反序列化漏洞,首先要掌握“序列化”(Serialization)和“反序列化”(Deserialization)这两个基础概念。
序列化:将内存中的 Java 对象转换为字节流的过程,以便于存储到磁盘或通过网络传输。
反序列化:将字节流重新还原为 Java 对象的过程。
这在分布式系统中极为常见,例如:
Dubbo、RMI 实现远程方法调用时的对象传递;
Redis 缓存 Java 对象;
消息队列(如 Kafka、RocketMQ)中传输复杂数据结构。
✅ 关键函数识别:
当代码中出现ObjectInputStream.readObject()、XMLDecoder.readObject()、JSON.parseObject()或ObjectMapper.readValue()等函数时,就可能存在反序列化操作,需重点关注安全性。
反序列化为何会成为漏洞?
表面上看,反序列化只是一个“恢复对象”的过程,但问题出在:
🔥 反序列化过程中会自动执行对象的某些特殊方法,如
readObject()、readResolve()、finalize()等。
如果攻击者能够控制输入的序列化数据,并精心构造一个恶意对象,那么在目标系统进行反序列化时,就会触发这些方法,从而执行任意代码!
漏洞形成三要素
可控输入:攻击者可以上传或发送自定义的序列化数据(如文件、HTTP 请求体、Socket 数据包)。
反序列化触发:服务端使用了
ObjectInputStream或其他易受攻击的库处理该数据。存在 Gadget 链(利用链):项目依赖的第三方库中存在可被组合利用的类,能最终调用到
Runtime.getRuntime().exec()执行系统命令。
一旦这三个条件同时满足,攻击者便可实现 远程代码执行(RCE),完全控制服务器!
经典案例回顾:那些年我们经历过的“核弹级”漏洞
1. Apache Commons Collections 反序列化漏洞(2015年)
这是最早引爆业界的 Java 反序列化漏洞之一。攻击者利用 InvokerTransformer 类结合 LazyMap 构造 Gadget 链,最终通过反射调用 Runtime.exec() 执行命令。
影响范围极广,涉及 WebLogic、Jenkins、OpenNMS 等数十款知名软件。
2. Fastjson 远程代码执行漏洞(≤1.2.47)
Fastjson 是阿里巴巴开源的高性能 JSON 库,因其默认开启 autotype 功能,允许通过 @type 字段指定反序列化的类名。
攻击者只需发送如下 JSON:
即可加载并执行一个由 bytecodes 指定的恶意类,实现 RCE。
3. Jackson 框架反序列化漏洞(启用 Default Typing)
当 Jackson 的 ObjectMapper 启用了 enableDefaultTyping() 功能时,支持多态反序列化。攻击者可通过 @class 指定恶意类,同样利用 TemplatesImpl 等 gadget 实现攻击。
攻击流程详解:黑客是如何一步步入侵的?
下面我们以经典的 CommonsCollections1 利用链为例,展示一次典型的反序列化攻击过程。
Step 1:准备恶意类
编写一个静态代码块中执行命令的类:
编译后得到 Exploit.class,并进行 Base64 编码。
Step 2:生成 Payload
使用神器 ysoserial 自动生成攻击载荷:
该工具内部已集成了多种成熟的 Gadget 链,可一键生成可用于不同场景的反序列化 payload。
Step 3:发送攻击数据
将 payload.bin 通过以下方式发送给目标系统:
HTTP 文件上传接口
自定义 TCP 协议通信
RMI 调用参数
Redis 缓存注入
Step 4:触发反序列化
目标服务器若存在如下代码,则会被成功利用:
结果:攻击者的命令将在服务器上以 JVM 权限运行,可能造成数据泄露、服务器被控、内网渗透等严重后果。
如何识别反序列化数据?特征分析
在实际攻防中,快速识别反序列化数据至关重要。
| 数据格式 | 特征 |
|---|---|
| Base64 编码流 | 以 rO0AB 开头(这是 aced0005 的 Base64 表示) |
| 十六进制流 | 以 aced0005 开头 |
| JSON 数据 | 包含 @type、@class、_type 等字段,常用于 Fastjson、Jackson |
例如:
只要看到这类数据出现在请求参数中,就要高度警惕是否存在反序列化风险。
防御方案:如何有效防范反序列化攻击?
✅ 1. 使用白名单机制
禁止反序列化未知类。对于 Fastjson,关闭 autotype 并注册安全类白名单:
对于 Jackson,避免使用 enableDefaultTyping(),改用 @JsonTypeInfo 显式声明类型。
✅ 2. 输入验证与过滤
对所有外部传入的数据进行严格校验,拒绝可疑的序列化流或 JSON 结构。
✅ 3. 依赖组件升级
及时更新第三方库,确保使用的 Fastjson、Jackson、XStream 等组件为最新安全版本。
| 组件 | 安全建议版本 |
|---|---|
| Fastjson | ≥ 1.2.83 |
| Jackson | ≥ 2.13.0 |
| XStream | ≥ 1.4.19 |
✅ 4. 使用安全替代方案
使用 JSON、Protobuf、Avro 等不支持任意对象反序列化的数据格式。
若必须使用 Java 原生序列化,应结合数字签名验证数据完整性。
✅ 5. 启用安全检测工具
在线扫描:使用 Burp Suite + Java-Deserialization-Scanner 插件。
本地检测:使用
ysoserial测试环境是否易受攻击(仅限授权测试)。静态分析:SonarQube、Fortify 等工具可帮助发现潜在风险代码。
安全无小事,细节决定成败
Java 反序列化漏洞虽非新话题,但由于其危害巨大且隐蔽性强,至今仍是企业安全防护的重点对象。它告诉我们:
🛡️ 不要信任任何来自外部的序列化数据!
无论是 RMI、Dubbo 接口,还是 JSON API、文件上传功能,只要涉及对象反序列化,就必须做好充分的安全防护。
作为开发者,我们应当:
深刻理解反序列化机制;
主动排查项目中的风险点;
采用最小权限原则设计系统架构;
持续关注安全社区动态,及时修复已知漏洞。
只有这样,才能在日益复杂的网络环境中,守住应用安全的第一道防线。





















