1

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

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

4

3 回答 3

2

一种(相当繁重但可行)的方法是:

  1. 使用 Java 代理转换所有已加载(过去和将来)的类,以便对列入黑名单的方法的调用实际上重定向到不同的方法。您可以为此使用ClassFileTransformerASM。因此,例如System.exit现在调用 to 将调用MySystem.exit. 当然MySystem不应该改造。
  2. 的代码可以基于例如变量MySystem.exit有条件地调用。System.exitThreadLocal
    公共类我的系统{
        private static final ThreadLocal callOriginal = new ThreadLocal();

        静态公共最终无效退出(int代码){
            if (Boolean.TRUE.equals (callOriginal.get ())) {
                System.exit(代码);
            }
        }
    }
  1. 对于要调用原始调用的线程,将其设置ThreadLocaltrue,其他线程设置为no

您可能想查看类似解决方案的时间机器库源代码。

于 2012-11-21T23:45:30.863 回答
1

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

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

也可以提供帮助。

于 2012-11-22T08:03:35.003 回答
1

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

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

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

于 2012-11-23T10:31:04.687 回答