简析CWE-391:未检查的错误情况缺陷漏洞
Java有两种类型的异常:已检查和未检查。
已检查的异常:编译器要求你必须处置的异常,代码还没运行,编译器就会检查你的代码,会不会出现异常,要求你对可能出现的异常必须做出相应的处理。
未检查的异常:编译器不要求强制处置的异常,不会在编译的时候检查,一一去检查会使得工作变得更加繁琐,只能在运行时才能检查出来,比如空指针异常等。
本期主题为未检查的错误情况漏洞的相关介绍。
一、什么是未检查的错误情况?
以Interrupted Exception为例,Interrupted Exception出现一般都是因为在线程执行的时候被打断(interrupt),线程(A)不是自己打断自己,一般都是在另外一个线程(B)中执行中断方法(objA.interrupt())。
每个线程都管理一个自己的中断状态(interruption status),它可以通过Thread#interrupt()方法设置位中断状态,或者使Thread#interrupted()重置状态。另外,Thread#is Interrupted()通常用来判断是否处于中断状态。
二、未检查的错误情况有什么危害?
若未检查的错误情况不能得到及时处理,会引起意想不到的攻击(OWASP-2004:A7中内有相应的记载),还是拿Interrupted Exception为例,不正确的错误处理和代码中不能忽略Interrupted Exceptions,只需将异常计数记录为“忽略”。这个抛出Interrupted Exception将清除线程的中断状态,因此如果异常处理不当,则线程被中断的消息将丢失。
三、如何处理未检查的错误情况?
Interrupted Exceptions应该立即或在清理之后重新抛出方法的状态,或线程应该通过调用Thread.interrupt() ,即使这是单线程应用。任何其他操作都有可能延迟线程关闭,并丢失线程被中断的信息(可能还没完成任务)。类似地,Thread Death异常也可能被传播。根据它的Java Doc,如果Thread Death被一个方法捕获,那么它必须被重新thrown,这样线程才会真正消亡。
四、含有“未检查的错误情况”缺陷的代码样例:
/**
Main processing method for the ThreadWatcher object
**/
public void run()
{
try
{
Tread.sleep(myTimeout);
}
catch (InterruptedException e)
{
// do nothing -- if watcher is interrupted, so is thread
}
interrupt;
}
}
使用Wukong软件代码安全检测修复系统检测上述程序代码,则可以发现代码中存在着“未检查的错误情况”的安全漏洞。请见下图: