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

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


答案 1

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

Java的设计非常强调使其成为一个安全的平台,具有静态类型安全管理器类加载器的规范使用,并且没有办法拧紧指针/内存。你可以阅读詹姆斯·高斯林(James Gosling)在《编程策划者》(Masterminds of Programming)中的采访,这很有趣。

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

但更微妙的事情也可能发生。例如,类装入器( 可以被认为是系统中的反射钩子) 在 Java 的早期版本中没有正确设计,导致潜在的类型替换。Gilad Bracha 撰写的《JVM 中的动态类加载》一文对这些问题很有见地。

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

  • strings不再是不可变的,可以更改(请参阅此问题)
  • 您可以揭示您不拥有的对象的合理信息
  • ...其他漏洞利用...

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

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

我已经阅读了@dbyrne指向的链接,但它主要是关于.net的。另外,我不知道Google App究竟禁用了什么。是仅反射权限,还是安全管理器的其他权限?一个危险显然是访问文件系统并搞砸了。

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

由于向下转换,类型安全也受到运行时错误的威胁,因此这一点也可以争论。

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

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


答案 2

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

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

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