对象反射的安全风险是什么?

时间:2010-06-09 03:22:11

标签: java security reflection code-access-security

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

5 个答案:

答案 0 :(得分:23)

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

java的设计非常注重使其成为一个安全的平台,静态类型安全管理器类加载器<的有条理使用/ strong>,无法搞砸指针/ 内存。你可以在Masterminds of programming阅读James Gosling的采访,这很有意思。

但是,更强大的反射能力,你越难以确保事情的安全。反射失败,特别是静态类型,可能导致运行时错误。

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

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

  • strings不再是不可变的,可以更改(请参阅此question
  • 您可以透露您不拥有的物品的合理信息
  • ......其他漏洞......

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

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

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

在实践中可以讨论访问私有数据和破坏封装的问题。编写安全代码确实非常困难,即使不更改访问修饰符,您也可以以不恰当的方式对类进行子类化 - 除非它们是final,或者更好,密封 - 并传递它们。这就是defensive copying试图防范的内容。

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

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

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

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

现在,假设允许反射。您could then walk the classloader hierarchy并枚举属于不同用户的WAR文件中的类/方法。显然,这是一个很大的问题。

答案 4 :(得分:0)

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

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