2012-11-21 104 views
1

我有一個模板系統允許用戶輸入模板源代碼並執行它們。模板源代碼可以訪問任何Java對象,包括System,Runtime和IO類。防止線程執行某些方法

的問題是如何防止執行線程與調用某些方法,如System.exitnew FileOutputStream

+1

您是否考慮過使用[SecurityManager](http://docs.oracle.com/javase/tutorial/essential/environment/security.html)? – assylias

+0

我不認爲'SecurityManager'可以阻止應用程序使用'System.exit()'。目的不是爲了保護應用程序本身,而是針對應用程序的系統。@green具有有限功能集的Java解釋器或某種類型的源代碼預處理器,用好的東西代替壞的方法 – zapl

+0

您可能需要面向方面的編程框架。我不太瞭解他們,但我認爲他們可以讓您將自定義安全策略添加到任何對象。 – didierc

回答

2

一(頗重,但可行)的方式來做到這一點是這樣的:

  1. 使用一個Java代理將所有加載的類(過去和將來)轉換爲類,以便黑名單方法的調用實際上被重定向到不同的方法。您可以使用ClassFileTransformerASM。所以例如致電System.exit現在將調用MySystem.exit。當然MySystem不應該被轉換。
  2. MySystem.exit的代碼可以有條件地基於例如System.exit來調用。在ThreadLocal變量上。
 
    public class MySystem { 
     private static final ThreadLocal callOriginal = new ThreadLocal(); 

     static public final void exit (int code) { 
      if (Boolean.TRUE.equals (callOriginal.get())) { 
       System.exit (code); 
      } 
     } 
    } 
  1. 對於要調用原始調用線程設置此ThreadLocaltrue,爲他人no

您可能需要查看time-machine類似解決方案的庫源代碼。

1

O有一些方法可以做到這一點。但最好的方式是使用安全管理器並編寫自己的類加載器(不要花太多時間,因爲谷歌搜索會給你很多例子:))。 當你加載一個類(這是在運行時編譯和加載的)到類加載器時,你需要指定安全管理器。在該代碼中,您可以提供這些限制。

我不知道它的法律鏈接與否,但this應該有所幫助。

This也可以提供幫助。

1

假設我們正在談論解釋器而不是生成的代碼。通過安裝SecurityManager,可以通過降低解釋器代碼權限的策略來降低權限。

如果使用java.security.AccessController.doPrivileged的雙參數形式,那麼調用方法會檢查直接調用者並忽略任何通過該調用方法的問題(例如,AccessController.doPrivileged)。

明顯託管不受信任的代碼會暴露一個巨大的攻擊面。您可以使用類加載器來隱藏自己的一些代碼,這些類加載器在類加載器層次結構中是彼此對等的。安全屬性package.access也很有用(儘管你仍然需要單獨的類加載器)。

+0

嗨,感謝您的輸入。你可以給我一些鏈接,以幫助我更好地理解如何在本文中建議使用ClassLoader實現SecurityManager? –