簡體   English   中英

使用 suppressAccessChecks 棄用和反射 SecurityManager

[英]SecurityManager deprecation and reflection with suppressAccessChecks

我是一名大學講師,我正在修改關於 Java 反思的演講。 其他幾年,當我講授 suppressAccessChecks 的可怕之處時,我展示了您可以設置一個 SecurityManager 並執行類似的操作

    if ("suppressAccessChecks".equals(p.getName())){
      StackTraceElement[] st = Thread.currentThread().getStackTrace();
      if(.. st ..) { throw new SecurityException(); }
    }

通過這種方式,您可以允許列入白名單的反序列化程序僅調用 suppressAccessChecks。 但是,現在他們正在棄用 SecurityManager。 我認為新的模塊系統應該在這里有所幫助,但我找不到資源來解釋如何支持上面列入白名單的反序列化器的想法。

有什么提示嗎?

對於 Java 模塊, setAccessible已經受到限制,即使沒有安全管理器也是如此:

class C中的調用者可以使用此方法來啟用對declaring class Dmember的訪問,如果以下任何一項成立:

  • CD在同一個模塊。
  • 成員是public的, D在 package 中是public的,包含D的模塊至少exports到包含C的模塊。
  • 成員protected staticD在 package 中public ,包含D的模塊導出到至少包含C的模塊, CD的子類。
  • D在 package 中,包含D的模塊至少向包含C的模塊opens 未命名和開放模塊中的所有包都對所有模塊開放,因此當D在未命名或開放模塊中時,此方法總是成功。

如果我們假設模塊 M 使用模塊 P 中的持久性服務的典型場景,並且無論如何都無法訪問成員,則只適用最后一個項目符號; M必須向P打開包以啟用訪問覆蓋。

這可以通過合格的opens指令來完成

module M {
  opens aPackage.needing.persistence to P;
}

這樣,只有明確指定的模塊,即P才能對aPackage.needing.persistence中的類型成員使用setAccessible

在 HotSpot JVM 的情況下,除了聲明的關系之外,還有選項--add-opens允許在啟動時添加合格的opens關系,但是沒有選項可以讓已經運行的應用程序的模塊在運行時創建這樣的關系自己獲得額外的訪問權限(除非安全性已經被破壞)。 可以想象其他環境甚至不支持這樣的啟動選項。


值得一提的是,仍然有一些新的限制無法通過這種方式規避。 正如setAccessible的文檔中所述:

此方法不能用於啟用對不可修改的最終字段的訪問。 以下字段是不可修改的:

  • static 在任何 class 或接口中聲明的最終字段
  • 隱藏的 class中聲明的最終字段
  • 記錄中聲明的最終字段

另請參閱此答案

換句話說,在record類型的情況下,持久性服務仍然必須使用構造函數來反序列化實例,即使在抑制訪問檢查時也是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM