java 对象反射的安全风险是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3002904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the security risk of object reflection?
提问by Legend
So after a few hours of workaround the limitation of Reflection being currently disabled on the Google App Engine, I was wondering if someone could help me understand why object reflection can be a threat. Is it because I can inspect the private variables of a class or are there any other deeper reasons?
因此,在解决了 Google App Engine 当前禁用反射的限制几个小时后,我想知道是否有人可以帮助我理解为什么对象反射可能是一种威胁。是因为我可以检查类的私有变量还是有其他更深层次的原因?
回答by ewernli
1 - Reflection (as a concept) is indeed orthogonal to safety/security.
1 - 反射(作为一个概念)确实与安全/安保正交。
There was a big emphasis in the design of java to make it a safe platform, with static typing, security manager, disciplined usage of class loader, and no way to screw pointers/memory. You can read the interview of James Gosling in Masterminds of programming, which is interesting about that.
java 的设计非常强调使其成为一个安全的平台,具有静态类型、安全管理器、类加载器的规范使用,并且没有办法破坏指针/内存。您可以阅读编程大师对 James Gosling 的采访,这很有趣。
But the more reflectivepower you have the harder it is to ensure things are safe as they should. Reflection defeat notably static typing and can lead to run-time errors.
但是,您拥有的反射能力越强,就越难确保事物应有的安全。反射尤其会破坏静态类型,并可能导致运行时错误。
But more subtle things can happen as well. For instance class loaders -- which can be considered as reflectivehook in the system -- were not designed properly in the early version of Java leading to potential type replacement. The article Dynamic class loading in the JVM,by Gilad Bracha, is insightful on such issues.
但更微妙的事情也可能发生。例如,类加载器——可以被认为是系统中的反射钩子——在 Java 的早期版本中设计不当,导致潜在的类型替换。Gilad Bracha撰写的 JVM 中的动态类加载一文对此类问题很有见地。
Reflection can not be turned off altogether; it's always possible to reflect on its own public fields/methods. Reflection on private structures with AccessibleObject.setAccessiblecan however be disabled, because it breaks encapsulation. With access to private fields, etc. inspection and modification of internal data is possible. It can lead to various malicious exploits, e.g.
反射不能完全关闭;总是可以反思自己的公共领域/方法。AccessibleObject.setAccessible但是可以禁用对私有结构的反射,因为它破坏了封装。通过访问私有字段等,可以检查和修改内部数据。它可能导致各种恶意利用,例如
stringsare not immutable anymore and can be changed (see this question)- you can reveal sensible information of objects you don't own
- ... other exploits ...
strings不再是一成不变的,可以改变(见这个问题)- 您可以透露不属于您的物品的合理信息
- ......其他漏洞......
Finally there are other mechanism that put security in jeopardy, notably sun.misc.Unsafewhich gives direct access to the memory -- pointers are back.
最后,还有其他机制将安全置于危险之中,特别是sun.misc.Unsafe它可以直接访问内存——指针又回来了。
2 - Now, the question is whether reflection (in practice) leads to that many risks.
2 - 现在,问题是反思(在实践中)是否会导致那么多风险。
I've read the link pointed by @dbyrnebut it's mostly about .net. Also I don't know exactly what is disabled for Google App. Is it the ReflectPermissiononly, or other permission of the security manager? One danger is clearly to get access to the file system and mess around.
我已经阅读了@dbyrne指向的链接,但它主要是关于 .net 的。我也不知道 Google App 究竟禁用了什么功能。它是ReflectPermission安全管理员的唯一权限还是其他权限?一种危险显然是访问文件系统并乱搞。
The problem of access to private data and breaking encapsulation can be argued in practice. Writing secure code is indeed extremely hard, and even without changing the access modifier you can subclass classes in an inappropriate way -- unless they are final, or even better, sealed -- and pass them around. This is for instance what defensive copyingtry to protect against.
在实践中可以争论访问私有数据和破坏封装的问题。编写安全代码确实非常困难,即使不更改访问修饰符,您也可以以不适当的方式对类进行子类化——除非它们是final密封的,或者更好的是密封的——然后传递它们。例如,这就是防御性复制试图防止的内容。
Type-safety is also anyway threatened by run-time error because of downcast, so this point can also be argued.
由于向下转型,类型安全无论如何也受到运行时错误的威胁,因此这一点也可以争论。
In a shared/hosted environment, the security is relative. At the language level, you can for instance not prevent a module form consuming 100% of CPU or consuming all memory up to a OutOfMemoryException. Such concerns need to be addressed by other means, typically at the OS level, with virtualization and quotas.
在共享/托管环境中,安全性是相对的。例如,在语言级别,您无法阻止模块形式消耗 100% 的 CPU 或消耗所有内存,最多OutOfMemoryException. 这些问题需要通过其他方式来解决,通常是在操作系统级别,使用虚拟化和配额。
So my personal answer, would be: reflection is a security risk, but not that big in practice if compared to other potential attack vectors.
所以我个人的回答是:反射是一种安全风险,但与其他潜在的攻击媒介相比,在实践中并没有那么大。
回答by Stephen C
An application can use the Java reflection APIs to access and update fields, and execute methods that are forbidden by normal Java access / visibility rules. With a bit of ingenuity, this is sufficient to:
应用程序可以使用 Java 反射 API 来访问和更新字段,并执行正常 Java 访问/可见性规则禁止的方法。有了一点独创性,这足以:
- access information that is supposed to be hidden,
- subvert the Java security sandbox so that you can interfere with other things running in the JVM, access files on the local machine, and so on.
- 访问应该隐藏的信息,
- 颠覆 Java 安全沙箱,以便您可以干扰 JVM 中运行的其他事物,访问本地机器上的文件,等等。
Under certain circumstances, it might even allow the injection of malicious native code.
在某些情况下,它甚至可能允许注入恶意的本机代码。
回答by Donal Fellows
First off, if you've not installed a SecurityManagerthen you're not secure anyway.
首先,如果您还没有安装,SecurityManager那么无论如何您都不安全。
Secondly, reflection doesn't open up significant holes unless the setAccessible()is enabled, and that itself is subject to a security check (governed by the setAccessChecksreflection permission). Without that, while you might be able to know that the private field or method exists (though that itself requires the accessDeclaredMembersruntime permission) you can't do anything much with that knowledge. Your best bet to attack might be to work with serialized objects, but that's a whole 'nother ball of wax.
其次,除非setAccessible()启用,否则反射不会打开重大漏洞,并且它本身受到安全检查(由setAccessChecks反射许可控制)。没有它,虽然您可能能够知道私有字段或方法存在(尽管它本身需要accessDeclaredMembers运行时权限),但您无法利用这些知识做任何事情。攻击的最佳选择可能是使用序列化对象,但这完全是“另一个蜡球”。
Note also that writing a secure security manager and class loader is non-trivial. Best to leave those to others if you're not aspiring to mega-guru-dom (or, more likely, embarrassing levels of failure).
另请注意,编写安全的安全管理器和类加载器并非易事。如果您不渴望成为超级大师(或者更有可能是令人尴尬的失败),最好将这些留给其他人。
回答by Sripathi Krishnan
GAE is a shared hosting environment, and hosts WAR files from multiple users. It is highly likely that multiple WAR files are hosted in the same JVM, because spawning a process per WAR is just ridiculous. So, the only way to sandbox each war file is via a custom classloader for each WAR file.
GAE 是一个共享托管环境,并托管来自多个用户的 WAR 文件。多个 WAR 文件很可能托管在同一个 JVM 中,因为为每个 WAR 生成一个进程是荒谬的。因此,沙箱每个 WAR 文件的唯一方法是通过每个 WAR 文件的自定义类加载器。
Now, assume that reflection was allowed. You could then walk the classloader hierarchyand enumerate classes/methods from WAR files belonging to different users. Obviously, that is a big concern.
现在,假设允许反射。然后,您可以遍历类加载器层次结构并从属于不同用户的 WAR 文件中枚举类/方法。显然,这是一个大问题。
回答by rook
A theory of mine is that Google is trying to hide something. By disabling ReflectionGoogle could hide Variable names, function calls and an even a full API. If Google is hiding something like an API, then they certainty aren't going to tell you about it.
我的一个理论是谷歌试图隐藏一些东西。通过禁用反射,谷歌可以隐藏变量名称、函数调用甚至一个完整的 API。如果谷歌隐藏了 API 之类的东西,那么他们肯定不会告诉你。
I know for a fact that Reflection plays a very important role in security testing. For instance you can automatically generate Fuzz tests using reflection. AxManuses TypeLib to identify all of the classes and their method calls that make up a COM object. Using this information AxMan will then instantiate each class and call every method with permutations of long strings and large numbers. Similar testing is conducted by SOAP Fuzzersusing the WSDL file for reflection.
我知道反射在安全测试中起着非常重要的作用。例如,您可以使用反射自动生成 Fuzz 测试。AxMan使用 TypeLib 来标识构成 COM 对象的所有类及其方法调用。使用此信息,AxMan 将实例化每个类并使用长字符串和大数字的排列调用每个方法。SOAP Fuzzers使用 WSDL 文件进行类似的测试以进行反射。

