kw和Fortify扫描中的修复ServerSocketChannel资源泄露引发的问题

     近期项目在使用kw和Fortify工具进行代码漏洞以及安全漏洞的扫描。对于扫描出来的海量漏洞,也确定出首要优先修复资源泄露类问题。不管是kw还是Fortify,其实扫描源码并不能做到绝对的智能。比如,在各种资源的关闭检查中,如果开发者封装了一个单独的方法用来释放资源,kw和Fortify是无法检测出来的,它们依旧会当成漏洞扫描出来。扫描出的漏洞数量非常大。但是也的确是有一部分的资源的确是没有释放的。
     对于扫描出来的漏洞,进行整改肯定是有利于代码健壮性以及产品安全性的。但是,一旦漏洞数量庞大,需要开发者在短期内修复大量扫描漏洞的时候,不可避免的就会发生问题。
     举一个由于修改资源释放漏洞而造成的更严重的问题。
     比如,如下这段代码:
    public void bind(SocketAddress address, IoHandler handler,IoFilterChain filterChain, String sessionClassName)
            throws IOException {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        ssc.socket().setReuseAddress(true);
        ssc.socket().bind(address);
        BindInfo info = new BindInfo(address, handler, filterChain, sessionClassName);
        ssc.register(selector, SelectionKey.OP_ACCEPT, info);
    }
     当开发者需要在短期内修改大量扫描漏洞的时候,很有可能无法详细读代码,无法确认代码功能,逻辑,上下文,甚至是jdk接口用法都不一定能够详细的了解。因为代码的修改者,很可能不是该模块的主要维护人员。
     从开发者的角度来看,该方法里面ServerSocketChannel作为一个方法变量,那么在方法中的finally块中将其释放,无可厚非,既然工具扫描出了该漏洞,工具认为ssc变量未能释放,那么就将其释放。但是,却忽略了另一个类变量:selector。
     我们来详细的解读一下ServerSocketChannel的用法,就很清楚问题出在哪里了。
     ServerSocketChannel ssc = ServerSocketChannel.open();------创建未绑定的ServerSocketChannel.
     ssc.configureBlocking(false);------将本ServerSocketChannel设置为非阻塞式
     ssc.register(selector, SelectionKey.OP_ACCEPT, info);------让侦听器selector侦听OP_ACCEPT事件,返回的是一个SelectionKey契约。这里的selector是一个类变量。
     在其他方法中,我们会这样使用:
     Set keySet = selector.selectedKeys();------返回selected-keys契约集
     然后通过契约集获取到ServerSocketChannel,再进行accept侦听操作。


     上述流程完全了解之后,我们自然就知道,在bind方法的finally块里面,将看上去是类变量的ssc直接close会造成什么问题。当ServerSocketChannel调用close方法时,将会关闭该通道,并且解除其一切契约,意味着在其他方法中,侦听器selector将无法得到ServerSocketChannel并进行侦听。


      事实上,如果开发者有足够的时间去了解代码的逻辑功能,了解ServerSocketChannel的用法,则不会造成上述问题。对于kw或者Fortify的代码扫描,当然是对代码健壮性和产品安全性的一个有益促进,但是,应该秉承一个原则:少量修改漏洞,仔细研读代码,全面覆盖测试。而不是流水线似的批量机械的操作。

你可能感兴趣的:(kw和Fortify扫描中的修复ServerSocketChannel资源泄露引发的问题)