JDK 17中的 java序列化过滤器 – Inside

21-10-26 banq

序列化过滤器首次出现在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 {

    @Override
    public Status checkInput(FilterInfo filterInfo) {
        ...
        return null;
    }
    
}

代码中定义的过滤器可以在 JVM 级别设置,甚至可以在单个流级别设置。

要在 JVM 范围内设置一个 fitler,setSerialFilter如下例所示:

ObjectInputFilter.Config.setSerialFilter(ObjectInputFilter);

要在单个流级别设置过滤器,请在要过滤setObjectInputFilter的流实例上使用:

ObjectInputStream.setObjectInputFilter(ObjectInputFilter);

 

猜你喜欢