阻止线程执行某些方法

时间:2012-11-21 23:03:18

标签: java multithreading security templating

我有一个模板系统允许用户输入模板源代码并执行它们。模板源代码可以访问任意Java对象,包括System,Runtime和IO类。

问题是如何防止执行线程调用某些方法,例如System.exitnew FileOutputStream等。

3 个答案:

答案 0 :(得分:2)

一种(非常重,但可行)的方法是:

  1. 使用Java代理转换所有已加载的(过去和将来)类,以便将列入黑名单的方法的调用实际重定向到其他方法。您可以使用ClassFileTransformerASM。所以例如现在调用System.exit会调用MySystem.exit。当然MySystem不应该被转换。
  2. MySystem.exit的代码可以有条件地调用System.exit,例如ThreadLocal。在ThreadLocal变量上。
  3.     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. 对于要调用原始调用的线程,将true设置为no,将其他设置设为{{1}}。
    2. 您可能希望查看类似解决方案的time-machine库源代码。

答案 1 :(得分:1)

有一些方法可以做到这一点。但最合适的方法是使用安全管理器并编写自己的类加载器(不应花费太多时间,因为谷歌搜索会给你很多例子:))。 当您将类(在运行时编译并加载)加载到类加载器时,您需要指定安全管理器。在该代码中,您可以提供限制。

我不知道它是否是合法链接,但this应该有所帮助。

This也可以提供帮助。

答案 2 :(得分:1)

假设我们正在讨论解释器而不是生成代码。安装SecurityManager后,可以通过使用减少解释器代码权限的策略来减少权限。

如果使用java.security.AccessController.doPrivileged的双参数形式,则调用方法会检查直接调用方并忽略传递的任何内容(例如,AccessController.doPrivileged)。

显然托管不受信任的代码会暴露巨大的攻击面。您可以通过使用类加载器来隐藏您自己的一些代码,类加载器是类加载器层次结构中的彼此对等的。安全属性package.access也很有用(尽管你仍然需要单独的类加载器)。