对象reflection的安全风险是什么?

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

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

java的设计非常注重使其成为一个安全的平台,具有静态类型安全管理器类加载器的规范使用,并且无法搞砸指针/ 内存 。 你可以在Masterminds编程中阅读James Gosling的访谈,这很有意思。

但是,你所拥有的反思能力越强,就越难以确保事情的安全。 reflection失败,特别是静态类型,可能导致运行时错误。

但也可能发生更微妙的事情。 例如,类加载器 – 可以被认为是系统中的reflection钩 – 在早期版本的Java中没有正确设计,导致潜在的类型替换。 由Gilad Bracha撰写的JVM动态类加载文章对此类问题非常有见地。

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

  • strings不再是不可变的,可以更改(请参阅此问题 )
  • 你可以揭示你不拥有的物体的合理信息
  • ……其他漏洞……

最后还有其他机制使安全性处于危险之中,特别是sun.misc.Unsafe ,它可以直接访问内存 – 指针又回来了。

2 – 现在,问题在于反思(在实践中)是否会导致许多风险。

我已经阅读了@dbyrne指出的链接,但它主要是关于.net的。 另外,我不确切知道Google App的禁用内容。 它只是ReflectPermission ,还是安全管理器的其他权限? 一个危险显然是访问文件系统并乱七八糟。

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

由于向下传播,类型安全性也受到运行时错误的威胁,所以这一点也可以争论。

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

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

应用程序可以使用JavareflectionAPI来访问和更新字段,并执行普通Java访问/可见性规则禁止的方法。 有点聪明才智,这足以:

  • 访问应该隐藏的信息,
  • 破坏Java安全沙箱,以便您可以干扰JVM中运行的其他内容,访问本地计算机上的文件等。

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

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

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

另请注意,编写安全的安全管理器和类加载器并非易事。 如果你不想要超级大师(或者更可能是令人尴尬的失败程度),最好把这些留给别人。

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

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

我的理论是谷歌试图隐藏某些东西。 通过禁用Reflection, Google可以隐藏变量名称,函数调用甚至是完整的API。 如果谷歌隐藏了类似API的东西,那么他们肯定不会告诉你它。

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