Class.forName 注入和构造函数调用

信息安全 爪哇 注射
2021-08-19 13:18:41

如果基于 Java 的网页采用用户提供的参数并使用

Class.forName(参数)
最坏的可能后果是什么?

攻击者确实获得了堆栈跟踪。对象被实例化后,它被强制转换为一个专有类,所以它会在那个时候抛出异常。

示例结果:

  • 枚举类路径上的类

编辑:攻击者还可以指定传递给构造函数的任意数量的字符串。

2个回答

这为滥用留下了很大的空间。基本上可以执行任何静态初始化程序和任何具有字符串参数的构造函数:这是 <something>(例如 JSON)对 Java 解析器的常见漏洞,它允许不受信任的数据块指定类名。

JDBC 驱动程序应该在静态初始化程序中注册自己。使用本机方法的类应该在静态 init 块中加载本机库。此外,还有一个在静态块中创建实例的单例反模式。所以有可能用完内存,不能被GCed。当然,有人可能已经编写了在静态 init 块中执行其他奇怪事情的代码。

有许多类在它们的构造函数中有副作用例如,使用文件名作为参数实例化FileOutputStream将清空该文件,假设 java 进程具有写权限。

在阅读帖子时,我想到了这些例子。我相信还有很多。

此外,您还应该考虑是否真的有必要向攻击者显示 Stacktraces。在意外情况下尽可能少地提供信息通常是一个好主意例如,在您的情况下,如果 FileInputStream 抛出 IOException 或 ClassCastException,它确实会有所不同。此信息可能会更容易利用另一个漏洞。

TrustedInterface.class.isAssinableFrom(loadedClass)在调用构造函数或使用之前,您至少必须进行检查loadedClass.asSubclass(TrustedInterface.class)但我强烈建议使用类名白名单。

Class.forName()就其本身而言,它并不是真正的水槽。这可能是一个漏洞,但这取决于如何class使用此方法调用返回的对象。

使用Class.forName()可能导致不安全反射,因为攻击者可能能够实例化他选择的类,然后在结果对象上调用方法调用。