反序列化风险与修复要点
序列化是把内存对象变成字节流,反序列化是把它还原回对象;还原过程会自动执行语言层面的钩子方法,例如 Java 的 readObject、PHP 的魔术方法、Python 的 reduce。攻击者一旦能控制这段字节流,就能借钩子方法在服务端拼出任意逻辑,而不需要注入命令或 SQL。修复的第一原则不是过滤输入,而是尽量不用原生反序列化承载跨边界数据。
基本信息
| 替代方案 | 跨边界数据改用 JSON、Protobuf 等纯数据格式 |
|---|---|
| 加固措施 | 反序列化类型白名单(默认拒绝)+ 数据签名与版本校验 |
| 隔离要求 | 处理进程最小权限,与关键系统网络隔离 |
| 关键动作 | 把所有反序列化入口收口到统一组件 |
典型使用场景
- Java 应用接收序列化字节流:远程调用、缓存、HTTP 会话与消息队列
- PHP 应用对用户输入调用反序列化函数,或使用可被伪造的会话文件
- Python 服务使用 pickle 在多进程或队列间传递对象
- 中间件与框架自身处理会话与状态数据,版本漏洞经由依赖引入
- 业务侧自定义缓存,把对象序列化后写入 Redis 等共享存储
加固清单
加固清单
1. 梳理全部反序列化入口,统一收口到公共组件 # 包括框架与依赖
2. 白名单按业务枚举可用类型,默认拒绝未登记类型
3. 数据传输加签名与版本号,拒绝不明版本与篡改数据
4. 处理进程降权运行,限制可访问的目录与网络
5. 对历史组件逐个核对官方公告,升级到声明修复该问题的版本
6. 升级后复查内嵌与传递依赖,避免只升了外层常见入口与处置方向
| 技术栈 | 典型入口 | 处置方向 |
|---|---|---|
| Java | 会话、缓存、远程调用、消息队列 | 升级组件;入口白名单;禁用危险类型 |
| PHP | 用户输入直接反序列化、会话与缓存 | 改用 JSON;校验数据签名与来源 |
| Python | pickle 跨进程或跨队列传输 | 改用 JSON;限制可导入符号 |
| .NET | 二进制格式化器还原对象 | 改数据格式;启用类型白名单机制 |
各语言的修复手法差异很大:先用官方安全公告确认该版本给出的正式处置方式,再谈自定义缓解措施。
反序列化问题通常直接对应服务端执行,验证阶段只做实现与配置核查,禁止构造利用链。