亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何檢查 SecurityManager 中的調用者類來源?

如何檢查 SecurityManager 中的調用者類來源?

不負相思意 2023-06-14 14:35:26
我有一個用于受信任的應用程序代碼的 ClassLoader 和一個用于用戶提交的(不受信任的)代碼的單獨的 ClassLoader。我希望安全管理器限制用戶提交的代碼。如何從 SecurityManager 中檢查調用方來源?查看偽代碼:System.setSecurityManager(new SecurityManager() {    public void checkPermission(Permission permission) {        if (/*caller class is not loaded by the trusted classloader*/) {            throw new SecurityException("You do not have permissions.");        }    }});我已經嘗試過的:StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass().getClassLoader()首先檢查權限,以便它給出堆棧溢出異常。Thread.currentThread().getStackTrace()[2].getClassLoaderName()是不安全的,因為它只提供類加載器名稱而不是類對象,如果不受信任的加載器的規范名稱與受信任的加載器相同,那么這是一個安全問題。
查看完整描述

2 回答

?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

首先,SecurityManager 有一個受保護的方法getClassContext()。
您的代碼如下所示:

System.setSecurityManager(new SecurityManager() {

? ? public void checkPermission(Permission permission) {

? ? ? ? Class<?> caller = getClassContext()[1];

? ? ? ? ClassLoader ccl = caller.getClassLoader();

? ? ? ? if (ccl != null || ccl != getClass().getClassLoader()) {

? ? ? ? ? ? throw new SecurityException("You do not have permissions.");

? ? ? ? }

? ? }

});

其次,如果要使用 a StackWalker,建議您復用StackWalker實例:


StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);

System.setSecurityManager(new SecurityManager() {

? ? public void checkPermission(Permission permission) {

? ? ? ? Class<?> caller = walker.getCallerClass();

? ? ? ? ClassLoader ccl = caller.getClassLoader();

? ? ? ? if (ccl != null || ccl != getClass().getClassLoader()) {

? ? ? ? ? ? throw new SecurityException("You do not have permissions.");

? ? ? ? }

? ? }

});

第三,這很可能不會做你想做的。安全檢查在整個 JDK 中完成,因此調用者可能在任意數量的堆棧級別之外,需要您檢查整個堆棧(提示:在您第二次訪問堆棧中的 SecurityManager 時中斷)。


相反,定義一個策略(創建一個 java 策略文件),您可以在其中授予您的代碼所有權限并使用 java.lang.SecurityManager。


如果無法編寫您自己的策略文件,您也可以使用Policy.setPolicy()安裝您自己的java.security.Policy.


一些實現 a 的提示java.security.Policy:

  • 覆蓋implies和兩種getPermissions方法。嚴重地。

  • 趕上你自己ProtectionDomain的政策類。(?private static final ProtectionDomain MY_PD = MyPolicy.class.getProtectionDomain())

  • 如果檢查是針對您自己的 ProtectionDomain,請使用快速路徑。


查看完整回答
反對 回復 2023-06-14
?
慕后森

TA貢獻1802條經驗 獲得超5個贊

我找到了一個臨時解決方案,但它并不完美:


System.setSecurityManager(new SecurityManager() {

    public void checkPermission(Permission permission) {

        Class<?> caller = SecurityManager.class;

        Class<?>[] classContext = this.getClassContext();

        int loopAmount = 0;


        while (caller.getCanonicalName() == null

                 || !caller.getCanonicalName().startsWith("nl")) {

            caller = classContext[loopAmount];

            loopAmount++;

        }


        if (caller.getClassLoader() != trustedClassLoader) {

            throw new SecurityException("You do not have permissions.");

        }

    }

});

所有不受信任的類的規范名稱都必須以“nl”開頭。這是 afaik 從類上下文中獲取調用者類的唯一方法,因為調用者類的數組位置未知,上下文數組的最后一個元素始終是具有 main 方法的類。


查看完整回答
反對 回復 2023-06-14
  • 2 回答
  • 0 關注
  • 151 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號