防范Java反序列化风险的关键是阻断不可信数据进入反序列化流程并切断恶意类加载与危险行为路径:禁用外部输入直连ObjectInputStream、强制ObjectInputFilter白名单、限制readObject等危险行为权限、优先采用JSON/gRPC等安全协议替代原生序列化。

防范 Java 反序列化安全风险,关键不是“加固反序列化过程”,而是不让不可信数据进入反序列化流程,并切断恶意类加载与危险行为执行的路径。
只对可信来源执行反序列化
任何来自外部的输入都不应直接交给 ObjectInputStream 处理:
- Web 接口中禁用
request.getInputStream() + ObjectInputStream解析用户提交内容 - RMI、JMS、Dubbo 等中间件需确认服务端未暴露默认反序列化入口(如禁用
UnicastRemoteObject.exportObject()) - 日志字段、调试参数、HTTP Header、Cookie 等看似无害的数据,一旦被用于构造对象或缓存键值,也需清洗或明确拒绝反序列化
强制启用类名白名单过滤器
Java 9+ 提供的 ObjectInputFilter 是目前最轻量且有效的运行时拦截手段:
- 必须在创建
ObjectInputStream后、调用readObject()前设置:ois.setObjectInputFilter(createFilter()) - 白名单规则应精确到具体类,例如
java.util.ArrayList;com.myapp.dto.Order;com.myapp.dto.User,避免使用com.myapp.*这类宽泛通配符 - 可配合 JVM 参数全局兜底:
-Djdk.serialFilter="maxdepth=10;maxarray=100000;deny=org.apache.commons.collections.*",但生产环境仍推荐代码级显式配置
封堵反序列化后的危险行为
即使类在白名单中,其 readObject()、静态块或 Transformer 链仍可能触发命令执行:
立即学习“Java免费学习笔记(深入)”;
- Java 8 及以前:通过
SecurityManager限制Runtime.exec、FilePermission、SocketPermission等关键权限 - Java 17+ 已移除
SecurityManager:改用字节码插桩(如 Byte Buddy)或 JVM Agent,在敏感方法入口动态注入检查逻辑 - 对已知高危 gadget 类(如
BadAttributeValueExpException、InvokerTransformer)在过滤器中明确加入黑名单
根本性规避:停用原生序列化
最彻底的防护是不给攻击者留门:
- HTTP 通信统一改用 JSON(Jackson/Gson),并关闭
enableDefaultTyping(),禁用自动类型推断 - RPC 场景优先选用 gRPC + Protobuf:协议强约束 schema,无反射、无动态类加载
- 若业务必须保留对象图还原能力,可考虑 Kryo(开启
RegistrationRequired)或 FST(配置安全模式),但需持续关注其维护状态与漏洞披露


















