本文目录导读:

序列化漏洞(通常指反序列化漏洞)是Java、PHP、.NET等语言中非常危险的高危漏洞,攻击者可以通过构造恶意序列化数据,在服务端反序列化时触发任意代码执行、命令执行或拒绝服务。
以下从检测和修复两个维度,结合主流语言(Java、PHP、Python、.NET)给出具体方案。
如何检测序列化漏洞
代码审计(静态检测)
Java 重点搜索:
ObjectInputStream.readObject()ObjectInputStream.readUnshared()readObject()方法自定义实现的类- 使用了
RMI、JMX、JMS、Hessian、Kryo、XStream、Fastjson、Jackson等框架的默认反序列化
PHP 重点搜索:
unserialize()函数__wakeup()、__destruct()、__toString()魔术方法- 使用了
phpggc等工具可以生成 gadget chain 的库
Python 重点搜索:
pickle.load()/pickle.loads()- 使用了
PyYAML、ruamel.yaml且未限制Loader类型 jsonpickle等库
C# / .NET 重点搜索:
BinaryFormatter.Deserialize()SoapFormatter.Deserialize()NetDataContractSerializerJavaScriptSerializer.Deserialize()(旧版)TypeNameHandling设置为Auto或All的Newtonsoft.Json
动态测试(黑盒/灰盒)
网络流量抓包:
- 使用 Burp Suite、Wireshark 抓取 HTTP 请求体、Cookie、隐藏字段
- 查找以下特征:
- 二进制序列化开头:
aced0005(Java 序列化魔数) - PHP 序列化字符串:
a:1:{s:4:...或O:8: - Base64 编码的序列化内容(解码后检查魔数)
- 自定义编码后的序列化数据
- 二进制序列化开头:
工具辅助检测:
- Java:
ysoserial生成 payload,逐个尝试不同的 gadget chain - PHP:
phpggc生成 payload - Python:
pickle恶意构造 - 通用: 使用
SerializationDumper解码二进制序列化,判断是否可被利用
安全扫描器:
- Burp Suite 的
Java Deserialization Scanner插件(自动检测 JDK 版本、gadget chain) - Nessus / OpenVAS 中相关的反序列化插件
日志监测
- 检查日志中是否有大量
ClassNotFoundException、IOException异常 - 检查是否有
readObject调用导致的异常堆栈,特别是涉及Runtime、ProcessBuilder、FileInputStream的调用
如何修复序列化漏洞
最彻底:避免使用不安全的反序列化
- 不使用
ObjectInputStream、unserialize()、pickle.loads()直接处理不可信数据 - 改用安全的格式替代:
- JSON(使用
Jackson或Gson,关闭enableDefaultTyping) - Protocol Buffers(gRPC)
- MessagePack(但需注意实现是否安全)
- YAML(需使用
SafeLoader,如yaml.safe_load())
- JSON(使用
输入校验与验证
-
白名单验证: 反序列化前校验数据类型、类名是否在允许列表中
- Java 示例:
ObjectInputStream ois = new ObjectInputStream(input) { @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { // 只允许反序列化指定的安全类 if (!desc.getName().equals("com.example.SafeUser")) { throw new InvalidClassException("Unauthorized deserialization", desc.getName()); } return super.resolveClass(desc); } };
- Java 示例:
-
签名校验(HMAC): 对序列化数据进行完整性校验,防止被篡改
// 写入时 byte[] data = serialize(user); byte[] hmac = computeHmac(data, secretKey); send(data + hmac); // 读取时 byte[] receivedData = ...; byte[] receivedHmac = ...; if (!verifyHmac(receivedData, receivedHmac, secretKey)) { throw new SecurityException("数据被篡改"); } Object obj = deserialize(receivedData);
使用安全的反序列化工具或过滤机制
Java:
- 使用
SerialKiller:开源的 Java 反序列化防火墙,支持黑/白名单 - 使用
ValidatingObjectInputStream(Apache Commons IO) - 使用
Hessian或Kryo(需关闭默认的auto-type功能) - 使用
Fastjson的SafeMode(1.2.68+)ParserConfig.getGlobalInstance().setSafeMode(true);
PHP:
- 使用
hash_equals对序列化字符串做 HMAC 校验 - 尽量使用
json_decode+json_encode替代 - 升级 PHP 版本,某些旧版本自动反序列化问题更严重
Python:
- 永远不要对不可信数据使用
pickle - 使用
yaml.safe_load()代替yaml.load() - 使用
json+ 自定义object_hook控制反序列化行为
限制反序列化来源
- 不要将反序列化接口暴露在公网,仅限内网或经过认证的客户端使用
- 添加 IP 白名单、Token 校验、CSRF 防护
- 对反序列化的数据大小做上限限制(防止内存耗尽攻击)
// 限制数据大小 byte[] data = readFromSocket(); if (data.length > 1024 * 1024) { // 1MB throw new SecurityException("数据过大"); }
升级依赖库版本
很多反序列化漏洞源于第三方库的 gadget chain:
| 库 | 已知漏洞版本(示例) | 安全版本(示例) |
|---|---|---|
| Commons Collections | ≤ 3.2.1 | 2.2+ |
| Commons BeanUtils | ≤ 1.9.3 | 9.4+ |
| Fastjson | ≤ 1.2.24 | 2.83+ |
| Jackson | 默认开启enableDefaultTyping | 关闭或升级 |
| Spring Framework | ≤ 4.2.4 | 3+ |
使用 OWASP Dependency Check 或 Snyk 自动检测依赖中的已知漏洞。
使用 RASP(运行时应用自我保护)工具
- OpenRASP(百度开源):在运行时拦截
readObject、Runtime.exec等敏感调用 - Contrast Security、Aqua Security:商业级 RASP 产品
针对特定语言的最佳实践
Java 示例(综合方案):
// 1. 使用安全的ObjectInputStream
public class SafeObjectInputStream extends ObjectInputStream {
private static final Set<String> WHITELIST = Set.of(
"java.lang.String",
"java.util.ArrayList",
"com.example.SafeUser"
);
public SafeObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!WHITELIST.contains(desc.getName())) {
throw new InvalidClassException("Blocked class: " + desc.getName());
}
return super.resolveClass(desc);
}
}
// 2. HMAC 校验
public static byte[] serializeWithHmac(Serializable obj, byte[] key) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.close();
byte[] data = bos.toByteArray();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key, "HmacSHA256"));
byte[] hmac = mac.doFinal(data);
ByteArrayOutputStream finalBos = new ByteArrayOutputStream();
finalBos.write(data);
finalBos.write(hmac);
return finalBos.toByteArray();
}
检测与修复优先级
| 优先级 | 动作 | 说明 |
|---|---|---|
| 最高 | 替换为安全格式(JSON/Protobuf) | 一劳永逸,彻底根除反序列化风险 |
| 高 | 升级依赖库版本 | 防止已知的gadget chain利用 |
| 高 | 添加HMAC签名校验 | 防止数据篡改,降低利用复杂度 |
| 中 | 实现白名单类验证 | 适用于必须使用序列化场景 |
| 中 | 使用RASP工具运行时检测 | 适合历史遗留系统无法快速改造 |
| 低 | 仅限制来源IP/认证 | 不能单独作为防护,需与其他配合 |
最终的铁律:永远不要对不可信数据直接进行反序列化。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播