21

我需要调用一些半可信的 Java 代码,并希望在该代码执行期间禁用使用反射的能力。

try{
   // disable reflection somehow
   someObject.method();
}
finally{
   // enable reflection again
}

这可以用 SecurityManager 来完成吗?如果可以,怎么做?

澄清/上下文:这是关于限制可以从 JavaScript/Rhino 调用的包的另一个问题的后续。接受的答案引用了一篇关于如何做到这一点的博客条目,它需要两个步骤,第一个步骤使用 Rhino API (ClassShutter),第二个步骤关闭反射和 Class.forName()。我在想我可以使用 SecurityManager 更干净地完成第二步(学习 SecurityManager,正如已经指出的那样,这是一个复杂的野兽,一路走来)。

总而言之,我希望(从代码,而不是设置文件)关闭 Class.forName() 以及对整个反射包的任何访问。

4

3 回答 3

20

这取决于您要限制的内容。

一般来说,可公开访问的 API 不受限制。但是,只要您不授予不可信代码ReflectPermission("suppressAccessChecks")权限,它就无法访问另一个包中的非公共 API。

如果您有要限制所有访问的软件包列表,则有两个步骤。首先,在Security属性中,将受限包包含在package.access列表中。然后给出你信任的代码RuntimePermission("accessClassInPackage." + pkg)

区分不受信任代码的常用方法是从不同位置加载它,并在授予权限时参考策略文件中的不同代码库。

Java 安全架构非常强大,但我知道它也很复杂;如果您想要一个更具体的示例,请准确描述您想要限制的调用,我会尝试更明确。


在不修改java.policy文件和/或java.security文件的情况下做你想做的事将非常困难,也许是不可能的。表示 中的java.security.Policy信息java.policy,但不提供写访问权限。您可以创建自己的Policy实现并在运行时安装它,只要任何现有的SecurityManager允许它。

另一方面,您可以将自定义 java.policy 文件指定为命令行选项。如果您要提供带有某种启动器的完整应用程序,那可能很容易实现。它还为您的用户提供了一些透明度。成熟的用户可以查看您希望授予应用程序的权限。

于 2009-04-21T01:01:56.347 回答
5

好吧,您可以覆盖SecurityManager.checkMemberAccess并给出更严格的定义。但是,它实际上并不是这样工作的。例如,如果代码定义了终结器,会发生什么?

关于澄清:其他 API 使用反射和其他 API。例如,java.beans、LiveConnect 和 Rhino。例如,攻击者可以从脚本中创建一个没有快门的新 Rhino 上下文,从而引导进入完整的 JRE。使用开放系统,黑名单永远无法完成。

总之:要使用 Java 安全模型,您需要使用它,而不是反对它。

于 2009-04-21T01:03:12.880 回答
2

我写了一个 ClassShutter 的替代品,它允许对每个实例、每个方法、每个字段进行细粒度的访问控制:

http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html

于 2010-07-27T17:52:34.763 回答