强化错误:代码正确性:错误的类比较

时间:2017-05-10 18:25:08

标签: java error-handling fortify

方法doRequest()根据第135行的类名确定对象的类型。这种做法可能导致意外行为或允许攻击者注入恶意类。

这是我的代码:

if(request.getClass().getName().equals(STRING_CONFIG))

所以STRING_CONFIG是一个字符串,而getName()给我一个字符串,所以这段代码出了什么问题?为什么Fortify测试会告诉我?

2 个答案:

答案 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)