序列化过滤器 - Sip of Java
Billy Korando 于 2021 年 10 月 14 日序列化过滤器在 JDK 9 中添加(请参阅 JEP 290),并在 JDK 17 中更新(请参阅 JEP 415)。序列化过滤器让 Java 应用程序可以更好地控制传入数据反序列化的方式。我们来看看为什么这很重要,以及如何配置序列化过滤器。
序列化的问题
Java 中的序列化长期以来一直是头疼的问题,因为它在实现方式上存在几个问题。其中一些问题包括
-
破坏封装
-
由“魔术”字段和方法控制的行为:
readObject
、writeObject
、readObjectNoData
、readResolve
、writeReplace
等。 -
还有更多!
过滤序列化数据
由于上面介绍的序列化实现问题,反序列化数据存在真正的风险,特别是不可信数据,此处有更详细的介绍。保护应用程序免受不安全反序列化攻击的有力工具是序列化过滤。
基于模式的过滤
可以通过模式配置过滤,该模式可以根据以下条件进行过滤
-
对象图的最大深度
-
对象图的最大引用
-
对象图的最大字节数
-
最大数组大小
-
根据类名、包名或模块名按类型允许或拒绝
请阅读 此处 了解如何构建模式。
将基于模式的过滤器设置为安全属性
可以通过添加 jdk.serialFilterFactory
将基于模式的过滤器设置为安全属性,如下面的示例所示
jdk.serialFilterFactory=<pattern>
到文件
$JAVA_HOME/conf/security/java.security
将基于模式的过滤器设置为 JVM 参数
还可以将基于模式的过滤器设置为 JVM 参数,如下面的示例所示
-Djdk.serialFilter=<pattern>
在代码中配置过滤器
也可以将过滤器配置为代码。
工厂过滤器
可以使用工厂方法来创建过滤器,方法是采用模式
ObjectInputFilter.Config.createFilter(String);
实现自定义过滤器
还可以实现接口 ObjectInputFilter
,以提供比基于模式的过滤器更灵活的序列化数据过滤功能
class Filter implements ObjectInputFilter {
@Override
public Status checkInput(FilterInfo filterInfo) {
...
return null;
}
}
在代码中设置过滤器
可以在 JVM 级别甚至在单个流级别设置在代码中定义的过滤器。
JVM 级过滤器
要在 JVM 级级别设置过滤器,请使用 setSerialFilter
,如下面的示例所示
ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter);
单个流级别
若要设置单个流级别的过滤器,请对要过滤的流实例使用 setObjectInputFilter
ObjectInputStream.setObjectInputFilter(ObjectInputFilter);
其他阅读材料
编码愉快!