2012-11-21 105 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? –