序列化过滤器 - Sip of Java

序列化过滤器在 JDK 9 中添加(请参阅 JEP 290),并在 JDK 17 中更新(请参阅 JEP 415)。序列化过滤器让 Java 应用程序可以更好地控制传入数据反序列化的方式。我们来看看为什么这很重要,以及如何配置序列化过滤器。

序列化的问题

Java 中的序列化长期以来一直是头疼的问题,因为它在实现方式上存在几个问题。其中一些问题包括

  • 破坏封装

  • “魔术”字段和方法控制的行为:readObjectwriteObjectreadObjectNoDatareadResolvewriteReplace 等。

  • 还有更多!

过滤序列化数据

由于上面介绍的序列化实现问题,反序列化数据存在真正的风险,特别是不可信数据,此处有更详细的介绍。保护应用程序免受不安全反序列化攻击的有力工具是序列化过滤。

基于模式的过滤

可以通过模式配置过滤,该模式可以根据以下条件进行过滤

  • 对象图的最大深度

  • 对象图的最大引用

  • 对象图的最大字节数

  • 最大数组大小

  • 根据类名、包名或模块名按类型允许或拒绝

请阅读 此处 了解如何构建模式。

将基于模式的过滤器设置为安全属性

可以通过添加 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);


其他阅读材料


编码愉快!