JDK 17中的 java序列化過濾器 – Inside

banq發表於2021-10-26

序列化過濾器首次出現在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);

 

相關文章