我有一个模板系统允许用户输入模板源代码并执行它们。模板源代码可以访问任意Java对象,包括System,Runtime和IO类。
问题是如何防止执行线程调用某些方法,例如System.exit
,new FileOutputStream
等。
答案 0 :(得分:2)
一种(非常重,但可行)的方法是:
System.exit
会调用MySystem.exit
。当然MySystem
不应该被转换。MySystem.exit
的代码可以有条件地调用System.exit
,例如ThreadLocal
。在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); } } }
true
设置为no
,将其他设置设为{{1}}。您可能希望查看类似解决方案的time-machine库源代码。
答案 1 :(得分:1)
有一些方法可以做到这一点。但最合适的方法是使用安全管理器并编写自己的类加载器(不应花费太多时间,因为谷歌搜索会给你很多例子:))。 当您将类(在运行时编译并加载)加载到类加载器时,您需要指定安全管理器。在该代码中,您可以提供限制。
我不知道它是否是合法链接,但this应该有所帮助。
This也可以提供帮助。
答案 2 :(得分:1)
假设我们正在讨论解释器而不是生成代码。安装SecurityManager
后,可以通过使用减少解释器代码权限的策略来减少权限。
如果使用java.security.AccessController.doPrivileged
的双参数形式,则调用方法会检查直接调用方并忽略传递的任何内容(例如,AccessController.doPrivileged
)。
显然托管不受信任的代码会暴露巨大的攻击面。您可以通过使用类加载器来隐藏您自己的一些代码,类加载器是类加载器层次结构中的彼此对等的。安全属性package.access也很有用(尽管你仍然需要单独的类加载器)。