21

因此,经过几个小时的解决方法,目前在 Google App Engine 上禁用了反射的限制,我想知道是否有人可以帮助我理解为什么对象反射可能是一种威胁。是因为我可以检查一个类的私有变量还是有其他更深层次的原因?

4

5 回答 5

25

1 - 反射(作为一个概念)确实与安全/安保正交。

Java 的设计非常强调使其成为一个安全的平台,具有静态类型安全管理器、类加载器的规范使用,并且没有办法拧指针/内存您可以阅读Masterminds of programming中对 James Gosling 的采访,这很有趣。

但是,您拥有的反思能力越强,就越难以确保事情应有的安全。反射会明显击败静态类型,并可能导致运行时错误。

但更微妙的事情也可能发生。例如,类加载器——可以被认为是系统中的反射钩子——在 Java 的早期版本中没有正确设计,导致潜在的类型替换。Gilad Bracha的文章Dynamic class loading in the JVM对这些问题有深刻见解。

反射不能完全关闭;总是可以反思自己的公共领域/方法。AccessibleObject.setAccessible但是可以禁用对私有结构的反射,因为它破坏了封装。通过访问私有字段等,可以检查和修改内部数据。它可能导致各种恶意攻击,例如

  • strings不再是不可变的并且可以更改(请参阅此问题
  • 您可以透露您不拥有的对象的敏感信息
  • ...其他漏洞利用...

最后,还有其他将安全置于危险境地的机制,特别是sun.misc.Unsafe它可以直接访问内存——指针又回来了。

2 - 现在,问题是反思(在实践中)是否会导致那么多风险。

我已经阅读了@dbyrne指向的链接,但它主要是关于.net 的。此外,我不确切知道 Google App 禁用了什么。它是ReflectPermission安全经理的唯一权限还是其他权限?一种危险显然是访问文件系统并搞乱。

在实践中可以争论访问私有数据和破坏封装的问题。编写安全代码确实非常困难,即使不更改访问修饰符,您也可以以不适当的方式对类进行子类化——除非它们是final密封的,甚至更好——并传递它们。例如,这是防御性复制试图防止的。

无论如何,类型安全也因为向下转换而受到运行时错误的威胁,所以这一点也可以争论。

在共享/托管环境中,安全性是相对的。例如,在语言级别,您可以不阻止一个模块形式消耗 100% 的 CPU 或消耗所有内存到OutOfMemoryException. 这些问题需要通过其他方式来解决,通常是在操作系统级别,包括虚拟化和配额。

所以我个人的回答是:反射是一种安全风险,但与其他潜在的攻击媒介相比,在实践中并没有那么大。

于 2010-06-09T06:24:15.090 回答
3

应用程序可以使用 Java 反射 API 访问和更新字段,并执行普通 Java 访问/可见性规则禁止的方法。有了一点独创性,这足以:

  • 访问本应隐藏的信息,
  • 颠覆 Java 安全沙箱,以便您可以干扰在 JVM 中运行的其他东西,访问本地机器上的文件等等。

在某些情况下,它甚至可能允许注入恶意本机代码。

于 2010-06-09T03:59:44.890 回答
3

GAE 是一个共享托管环境,托管来自多个用户的 WAR 文件。多个 WAR 文件很可能托管在同一个 JVM 中,因为为每个 WAR 生成一个进程实在是太荒谬了。因此,对每个 WAR 文件进行沙箱化的唯一方法是通过每个 WAR 文件的自定义类加载器。

现在,假设允许反射。然后,您可以遍历类加载器层次结构并从属于不同用户的 WAR 文件中枚举类/方法。显然,这是一个大问题。

于 2010-06-09T09:16:35.283 回答
2

首先,如果您还没有安装,SecurityManager那么无论如何您都不安全。

其次,除非启用了反射,否则反射不会打开重大漏洞setAccessible(),并且它本身会受到安全检查(由setAccessChecks 反射权限管理)。没有它,虽然您可能能够知道私有字段或方法存在(尽管它本身需要accessDeclaredMembers 运行时权限),但您无法利用这些知识做任何事情。你最好的攻击选择可能是使用序列化的对象,但那是一个完整的“另一个蜡球”。

另请注意,编写安全的安全管理器和类加载器并非易事。如果您不渴望成为超级大师(或者更有可能是令人尴尬的失败程度),最好将这些留给其他人。

于 2010-06-09T08:20:10.847 回答
0

我的一个理论是谷歌试图隐藏一些东西。通过禁用反射 ,谷歌可以隐藏变量名称、函数调用甚至完整的 API。如果 Google 隐藏了 API 之类的东西,那么他们肯定不会告诉你这件事。

我知道反射在安全测试中起着非常重要的作用。例如,您可以使用反射自动生成 Fuzz 测试。AxMan使用 TypeLib 来识别构成 COM 对象的所有类及其方法调用。使用此信息,AxMan 将实例化每个类并使用长字符串和大数字的排列调用每个方法。SOAP Fuzzers使用 WSDL 文件进行反射进行类似的测试。

于 2010-06-09T07:47:01.987 回答