方法doRequest()根据第135行的类名确定对象的类型。这种做法可能导致意外行为或允许攻击者注入恶意类。
这是我的代码:
if(request.getClass().getName().equals(STRING_CONFIG))
所以STRING_CONFIG是一个字符串,而getName()给我一个字符串,所以这段代码出了什么问题?为什么Fortify测试会告诉我?
答案 0 :(得分:3)
STRING_CONFIG是一个字符串,getName()给我一个字符串,所以这段代码出了什么问题?
Fortify不会测试是否符合语言限制 - 这是编译器的工作。因此,它的抱怨与一般是否有意义通过一个String
方法比较两个equals()
无关。它实际上设法执行更深层次的语义分析,以确定(正确地)您正在尝试通过其类的名称来确定对象的类型,正如消息所说的那样。
为什么Fortify测试会告诉我这个?
因为即使类的完全限定名称也不能在可能的类的Universe中唯一地标识它,甚至不一定在应用程序可以访问的类的Universe中。类由加载它们的ClassLoader
确定范围,因此可以有多个具有给定完全限定名称的同时加载到同一VM中的名称。至少存在一种假设的风险,即某个给定名称的恶意类的对象已经注入到您的应用程序中,如果您将其视为不同但同名的类的对象,则会造成严重破坏。
不是通过Strings
比较班级名称equals()
,而是通过Class
比较==
个对象,或者使用instanceof
运算符:
if (request.getClass() == my.package.ClassIWasExpecting.class) {
// ...
} else if (request instanceof my.package.OtherAcceptableClass) {
// ...
}
请注意,instanceof
提供的特定标准不如类比较。
仍有一些潜在的恶意类被注入,但它必须以不同的方式发生,更难以达到这一点。
答案 1 :(得分:0)
识别对象是否是类的实例的正确方法是使用instanceof
其他任何人都可以使用您的类的同名创建一个类(和包)并欺骗这段代码。这是什么强化要点。
如果你的代码是
private static final String STRING_CONFIG = "com.abc.Test";
if(request.getClass().getName().equals(STRING_CONFIG))
将此段代码更改为
if(request instanceof com.abc.Test)