3

在我们的应用程序中,用户能够定义由我们的主引擎执行的 Java 表达式(这些表达式只是方法调用:例如 Math.abs(42) )。它们是通过反射执行的。

有哪些不同的解决方案可以直接或通过最终在内部调用 System.exit 的方法调用来防止那些表达式调用例如 System.exit (但还有文件访问和其他......)?

请注意,可以在不同的线程中执行几个不同的表达式。例如,使用 SecurityManager 阻止文件访问不起作用,因为在执行表达式时主引擎必须仍然能够访问文件系统。

4

5 回答 5

5

你说你不能使用是错误的SecurityManager——这正是它的用途:托管不受信任的代码,如在 Applet 容器或 RMI 服务器中。现代的 SecurityManager 配置了策略文件,这些文件授予特定的细粒度权限,包括对文件系统的有限访问。您需要使用 SecurityManager,但您需要成为它的专家。

这是一个巨大的话题;最好的办法是谷歌“Java 安全策略文件”并阅读所有你能读到的东西。

于 2012-08-02T11:05:36.243 回答
4

你在做什么是疯狂的。允许用户在你的机器上执行任意 Java 代码是一个糟糕的想法,而且你无法确保它对知道他们的东西的黑客安全。

我能想到的唯一解决方案是创建一个可能使用的包和方法的白名单。但是尝试将特定操作列入黑名单永远不会让您到达那里。在破坏东西方面,总会有人比你更聪明。

更新:我现在已经阅读了更多关于SecurityManager它的信息,而且您似乎可以很好地控制包访问,所以我建议您使用 Ernest 的回答。

于 2012-08-02T11:01:31.230 回答
3

Java 安全系统是用于此目的的合适工具。SecurityManager只是您必须使用的该系统的一部分。

基本上,您不会自己调用不受信任的代码。相反,您将该调用包装成 aPrivilegedAction并将其提供给其中一个AccessController.doPrivileged方法。然后不受信任的代码将在另一个ProtectionDomain.

因此,您必须配置两个保护域:一个用于具有完全权限的引擎,另一个用于具有降低权限的不受信任的代码。

但正如欧内斯特已经提到的:这是相当复杂的东西,不适合像这样的问答网站。阅读 Oracle 和 Co. 提供的相应教程。使用上述关键字进行搜索。

于 2012-08-02T11:17:01.160 回答
2

例如 Apache Velocity 有一个类似的问题需要解决。他们使用velocity.properties中定义的黑名单类和包:

# ----------------------------------------------------------------------------
# SECURE INTROSPECTOR
# ----------------------------------------------------------------------------
# If selected, prohibits methods in certain classes and packages from being 
# accessed.
# ----------------------------------------------------------------------------

introspector.restrict.packages = java.lang.reflect

# The two most dangerous classes

introspector.restrict.classes = java.lang.Class
introspector.restrict.classes = java.lang.ClassLoader

# Restrict these for extra safety

introspector.restrict.classes = java.lang.Compiler
introspector.restrict.classes = java.lang.InheritableThreadLocal
introspector.restrict.classes = java.lang.Package
introspector.restrict.classes = java.lang.Process
introspector.restrict.classes = java.lang.Runtime
introspector.restrict.classes = java.lang.RuntimePermission
introspector.restrict.classes = java.lang.SecurityManager
introspector.restrict.classes = java.lang.System
introspector.restrict.classes = java.lang.Thread
introspector.restrict.classes = java.lang.ThreadGroup
introspector.restrict.classes = java.lang.ThreadLocal
于 2012-08-02T11:19:09.703 回答
1

Java中有太多东西可能会导致您可能没有意识到的问题。最安全的做法是创建一个允许的类列表,并通过自定义类加载器在单独的进程中运行这些类(这样你就可以安全地杀死它)

对于大多数人甚至不知道的严重危险代码,请查看sun.misc.Unsafe,它可以让您

  • 访问内存的随机区域。
  • 创建类的新实例而不调用构造函数,例如枚举的新实例。
  • 离散地锁定和解锁对象监视器。(没有同步块)
于 2012-08-02T11:35:27.150 回答