java原生序列化不适用于不可信网络环境,2026年已被列为高危技术;必须禁用未经校验的readobject调用,启用objectinputfilter白名单,并优先采用protobuf、avro等安全替代方案。

Java原生序列化机制本身不适用于不可信网络环境下的对象传输——它不是为安全通信设计的,而是为JVM内部可信场景(如RMI调用、本地缓存)提供的便捷工具。2026年主流实践已明确将其列为高危技术,尤其在跨服务、跨域或面向公网的数据交互中,直接使用 ObjectInputStream 反序列化网络字节流,等于向攻击者敞开RCE大门。
必须避免的危险操作
以下行为在生产环境中应被禁止:
- 从HTTP请求体、Socket输入流、MQ消息体等外部来源,未经校验直接调用
ObjectInputStream.readObject() - 将
Serializable对象作为REST API响应体或前端可读字段(如Base64编码后暴露) - 依赖未加固的第三方组件(如旧版 Apache Commons Collections、Groovy、Spring Boot Actuator)接收序列化数据
- 重写
readObject方法但未做输入合法性检查,或在其中执行动态类加载、命令执行等敏感操作
若业务强依赖原生序列化,必须启用白名单过滤
自 Java 9 起,ObjectInputStream 支持 ObjectInputFilter;Java 17+ 默认启用更严格的默认策略。关键配置如下:
- 创建白名单过滤器,只允许明确声明的类及其子类:
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter("com.example.model.User;java.util.ArrayList;!*"); - 在反序列化前绑定过滤器:
ObjectInputStream ois = new ObjectInputStream(inputStream);<br>ois.setObjectInputFilter(filter);
- 禁止通配符泛滥(如
*;*或!*),禁用sun.*、org.apache.commons.collections.*等高危包路径 - 将过滤策略配置为 JVM 启动参数(更可靠):
-Djdk.serialFilter="maxdepth=5;maxarray=1000000;com.example.**;java.lang.String;java.lang.Integer"
替代方案:用现代序列化协议代替原生机制
金融、电商、游戏等对延迟和安全性要求高的系统,2026年已全面转向零拷贝、Schema驱动的替代方案:
- Protocol Buffers(Protobuf):需定义 .proto 文件,生成类型安全的 Java 类;无反射开销,体积小,天然防 gadget chain
- Apache Avro:支持 schema 演进,适合大数据管道;序列化数据自带 schema ID,便于版本兼容控制
- FlatBuffers(C++/Java/Go 多语言支持):真正零拷贝,无需反序列化即可访问字段,适用于高频实时场景
- 若需文本格式,选用严格配置的 JSON-B / Jackson(禁用 DefaultTyping),并配合 JSON Schema 校验
运行时防护与监控建议
即便做了白名单,也应叠加纵深防御:
- 在 JVM 启动时添加 Java Agent(如
ysoserial-detector或自研插桩),记录所有ObjectInputStream.readObject()调用栈及类名 - 对反序列化入口点(如 RMI Registry、JMX Connector、自定义 Socket Server)做网络层隔离,仅限内网互通
- 日志中记录每次反序列化的源 IP、目标类名、时间戳;设置告警规则,如 1 分钟内出现 3 次非白名单类尝试
- 定期扫描依赖树,移除含已知 gadget 的库版本(例如:Apache Commons Collections
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











