序列化过滤器首次出现在JDK 9,在 JDK 17获得更新,序列化过滤器使 Java 应用程序可以更好地控制传入数据的反序列化方式。
Java 中的序列化长期以来一直是一个令人头疼的问题,与它的实现方式有关的几个问题有关。其中一些问题包括:
- 打破封装
- 行为研究受控“魔术师”域和方法:readObject,writeObject,readObjectNoData,readResolve,writeReplace,等。
序列化过滤可用于保护您的应用程序免受不安全反序列化攻击。
过滤可以通过一个模式进行配置,该模式可以基于以下条件进行过滤:
- 对象图的最大深度
- 对象图的最大引用数
- 对象图的最大字节数
- 最大数组大小
- 根据类名、包名或模块名按类型允许或拒绝
阅读此处了解如何构建模式。
三种使用方式
- 设置为安全属性
在文件:
$JAVA_HOME/conf/security/java.security
中添加:
jdk.serialFilterFactory=<pattern>
- 设置为 JVM 参数
-Djdk.serialFilter=<pattern>
- 在代码中定义过滤器
可以使用工厂方法通过采用模式来创建过滤器:
ObjectInputFilter.Config.createFilter(String);
也可实施自定义过滤器:
ObjectInputFilter与基于模式的过滤器相比,该接口还可以实现为过滤序列化数据提供更大的灵活性:
class Filter implements ObjectInputFilter { |
代码中定义的过滤器可以在 JVM 级别设置,甚至可以在单个流级别设置。
要在 JVM 范围内设置一个 fitler,setSerialFilter如下例所示:
ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter);
要在单个流级别设置过滤器,请在要过滤setObjectInputFilter的流实例上使用:
ObjectInputStream.setObjectInputFilter(ObjectInputFilter);