简介

JEP 290 是在 Java9 新增的一个安全机制,可以增加反序列化过程的安全性,并向下引进到了 JDK 6/7/8 中。它主要提供了以下功能:

  1. 提供反序列化类的黑白名单;
  2. 限制反序列化的深度和复杂度;
  3. 为 RMI 远程调用对象提供了类验证机制;
  4. 可以自定义过滤配置,比如通过 properties 文件的形式。

其核心逻辑通过实现 ObjectInputFilter 完成,然后调用 setInternalObjectInputFilter 将 filter 对象(属性)设置给 ObjectInputStream。

在 ObjectInputStream 的构造函数中,也会调用静态内部类 Config 的方法来获取 serialFilter 对象:

Config 类

Config 是 ObjectInputFilter 的一个内部静态类,内容大致如下:

其中类属性 configuredFilter 会在类初始化时赋值:

可以看到会从 JVM 或者 %JAVA_HOME%\conf\security\java.security 文件的 jdk.serialFilter 属性中获取过滤器。

总结

Config 静态类在初始化的时候,会将 Config.serialFilter 赋值为一个 Global 对象,这个 Global 对象的 filters 字段值是 jdk.serailFilter 属性对应的 Function 列表。

而 ObjectInputStream 的构造函数中,正好取的就是 Config.serialFilter 这个静态字段, 所以设置了 Config.serialFilter 这个静态字段,就相当于设置了 ObjectInputStream 类 全局过滤器。

有一些框架会在初始化时设置 Config.serialFilter 来配置 ObjectInputStream 的全局过 滤,比如 weblogic 启动时会将这属性设置为 WebLogicObjectInputFilterWrapper 对象。

内置过滤器

JEP290 默认只为 RMI 注册表(RMI Register 层)、 RMI 分布式垃圾收集器(DGC 层)以及 JMX 提供了相应的内置过滤器,其他情况需要手动设置。

RMI Registry 有一个内置的白名单过滤器,允许将对象绑定到注册表中:

  • java.rmi.Remote
  • java.lang.Number
  • java.lang.reflect.Proxy
  • java.rmi.server.UnicastRef
  • java.rmi.activation.ActivationId
  • java.rmi.server.UID
  • java.rmi.server.RMIClientSocketFactory
  • java.rmi.server.RMIServerSocketFactory

RMI 分布式垃圾收集器内置的白名单过滤器:

  • java.rmi.server.ObjID
  • java.rmi.server.UID
  • java.rmi.dgc.VMID
  • java.rmi.dgc.Lease