[英]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
D
的member
的訪問,如果以下任何一項成立:
如果我們假設模塊 M 使用模塊 P 中的持久性服務的典型場景,並且無論如何都無法訪問成員,則只適用最后一個項目符號; M
必須向P
打開包以啟用訪問覆蓋。
這可以通過合格的opens
指令來完成
module M {
opens aPackage.needing.persistence to P;
}
這樣,只有明確指定的模塊,即P
才能對aPackage.needing.persistence
中的類型成員使用setAccessible
。
在 HotSpot JVM 的情況下,除了聲明的關系之外,還有選項--add-opens
允許在啟動時添加合格的opens
關系,但是沒有選項可以讓已經運行的應用程序的模塊在運行時創建這樣的關系自己獲得額外的訪問權限(除非安全性已經被破壞)。 可以想象其他環境甚至不支持這樣的啟動選項。
值得一提的是,仍然有一些新的限制無法通過這種方式規避。 正如setAccessible
的文檔中所述:
此方法不能用於啟用對不可修改的最終字段的寫訪問。 以下字段是不可修改的:
另請參閱此答案
換句話說,在record
類型的情況下,持久性服務仍然必須使用構造函數來反序列化實例,即使在抑制訪問檢查時也是如此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.