禁用当前线程的 Java 反射
我需要调用一些半可信的 Java 代码,并希望在该代码执行期间禁用使用反射的功能。
try{
// disable reflection somehow
someObject.method();
}
finally{
// enable reflection again
}
这可以通过 SecurityManager 来完成吗?如果可以,如何实现?
澄清/上下文:这是另一个问题,关于限制可以从 JavaScript/Rhino 调用的包。 接受的答案引用了一篇关于如何做到这一点的博客文章,它需要两个步骤,第一个步骤使用 Rhino API (ClassShutter),第二个步骤关闭反射和 Class.forName()。 我想我可以使用 SecurityManager 更干净地完成第二步(学习 SecurityManager,正如已经指出的那样,这是一个复杂的野兽,一路走来)。
总而言之,我想(从代码中,而不是设置文件中)关闭 Class.forName() 以及对整个反射包的任何访问。
I need to call some semi-trustworthy Java code and want to disable the ability to use reflection for the duration of that code's execution.
try{
// disable reflection somehow
someObject.method();
}
finally{
// enable reflection again
}
Can this be done with a SecurityManager, and if so, how?
Clarification/Context: This is a follow-up to another question about restricting the packages that can be called from JavaScript/Rhino. The accepted answer references a blog entry on how to do that, and it requires two steps, the first one using a Rhino API (ClassShutter), the second one turning off reflection and Class.forName(). I was thinking I can do that second step more cleanly using a SecurityManager (learning about SecurityManager, which as has been pointed out, is a complex beast, along the way).
To sum up, I want (from code, not setting file) to turn off Class.forName() and any access to the whole reflection package.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这取决于您想要限制什么。
一般来说,公开访问的 API 不受限制。 但是,只要您不授予不可信代码
ReflectPermission("suppressAccessChecks")
权限,它将无法访问其他包中的非公共 API。如果您有一个要限制所有访问的软件包列表,则有两个步骤。 首先,在
Security
属性中,将受限包包含在package.access
列表中。 然后提供您的可信代码RuntimePermission("accessClassInPackage." + pkg)
。区分不受信任代码的常见方法是从不同位置加载它,并在授予权限时引用策略文件中的不同代码库。
Java安全架构非常强大,但我知道它也很复杂; 如果您想要一个更具体的示例,请准确描述您想要限制的调用,我会尽力更明确。
要在不修改
java.policy
文件和/或java.security
文件的情况下完成您想要的操作将非常困难,甚至是不可能的。java.security.Policy
表示java.policy
中的信息,但它不提供写访问权限。 您可以创建自己的Policy
实现,并在运行时安装它,只要任何现有的SecurityManager
允许即可。另一方面,您可以指定自定义 java.policy 文件作为命令行选项。 如果您提供带有某种启动器的完整应用程序,那么这可能很容易完成。 它还为您的用户提供了一定的透明度。 经验丰富的用户可以查看您想要授予应用程序的权限。
It depends on what you are trying to restrict.
In general, publicly accessible API is not restricted. However, as long as you don't grant the untrustworthy code the
ReflectPermission("suppressAccessChecks")
permission, it won't be able to get access to non-public API in another package.If you have a list of packages to which you want to restrict all access, there are two steps. First, in the
Security
properties, include the restricted package in thepackage.access
list. Then give your trusted codeRuntimePermission("accessClassInPackage." + pkg)
.A common way to distinguish your untrusted code is to load it from a different location, and refer to the different codebases in your policy file when granting permissions.
The Java security architecture is very powerful, but I know it is also complicated; if you would like a more concrete example, please describe exactly what calls you want to restrict and I'll try to be more explicit.
To do what you want without modifying the
java.policy
file and/or thejava.security
file would be very difficult, maybe impossible. Thejava.security.Policy
represents the information injava.policy
, but it doesn't offer write access. You could create your ownPolicy
implementation and install it at runtime as long as any existingSecurityManager
permits it.On the other hand, you can specify a custom java.policy file as a command-line option. If you are providing a complete application with some sort of launcher, that might be easily accomplished. It also provides some transparency to your users. A sophisticated user can review the permissions you'd like to have granted to the application.
那么,您可以覆盖 SecurityManager.checkMemberAccess 并给出更严格的定义。 然而,它实际上并不是这样工作的。 例如,如果代码定义了终结器,会发生什么?
关于澄清:其他API使用反射和其他API。 例如,java.beans、LiveConnect 和 Rhino。 例如,攻击者可以在脚本中创建一个新的 Rhino 上下文,而无需快门,从而引导到完整的 JRE。 对于一个开放的系统来说,黑名单是永远不可能完成的。
总之:要使用 Java 安全模型,您需要使用它,而不是反对它。
Well, you can override
SecurityManager.checkMemberAccess
and give a stricter definition. However, it doesn't really work like that. What happens for instance if the code defines a finaliser?On the clarification: Other APIs use reflection and other APIs. For instance, java.beans, LiveConnect and Rhino. An adversary could from within a script, say, create a new Rhino context without the shutter and thereby bootstrap into the full JRE. With an open system, a blacklist can never be finished.
In summary: to use the Java security model you need to work with it, not against it.
我编写了 ClassShutter 的替代品,它允许对每个实例、每个方法、每个字段进行细粒度访问控制:
http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html
I wrote a replacement of ClassShutter that allows fine grained access control, per instance, per method, per field:
http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html