开源静态代码审计软件分析比对

考量点

静态代码审计目前比较好的案例有Android团队改造的静态检查组合sonarLint + findbugs + Android Lint 。但是对于服务器端代码质量和安全方面都检测手段还是严重不足的。目前的开源工具普遍适用于表现在对代码检测,而不是安全检测,发现着重于bug而不是vulnerabilities。

开源工具介绍

参与此次分析的软件有以下工具

  1. https://github.com/google/shipshape
    这是google发布一个静态程序分析平台,采用go语言编写,支持js、java、python以docker镜像方式运行。可以通过对接api使用go语言和java(暂无介绍)实现分析器。最近代码更新于两年前,目前有176 star。

  2. https://github.com/google/error-prone
    errorprone同样是google出品,已经支持集成在shipshape(checkstyle、findbugs也支持)上。主要用在google内部的java编译系统中来发现严重的code mistakes。特点在于静态类型分析检查,可以发现一些编译过程中不易被发现的错误。优点在于hooks在build过程,成熟度高可以保证集成在ci中。支持快速部署在Maven和gradle脚本中。

  3. https://github.com/facebook/infer
    infer是Facebook出品,使用OCaml编写的的静态分析语言,支持java、object c和c语言。可以检查java和android程序的空指针异常、自由泄漏、资源竞争条件等漏洞。市场反应好,star数8182。

  4. fireline- http://magic.360.cn/zh/index.html
    360Web平台部Qtest团队开发的一款免费静态代码分析工具。主要针对移动端Android产品进行静态代码分析。其最为突出的优点就是资源泄漏问题的全面检测。同时,火线与360信息安全部门合作,推出了一系列针对移动端安全漏洞的检测规则。免费使用,并支持Android Studio插件,Jenkins插件,Gradle部署等多种集成方式。

  5. https://spotbugs.github.io/
    spotbugs专注与java程序的老牌bug检测工具。支持规则和种类较多。

  6. https://github.com/find-sec-bugs/find-sec-bugs/

  7. findsecuritybugs更专注于javaweb和安卓漏洞的发现,拥有125种漏洞判断类型, 787 个api的特征检测。

测试方案

根据wiki中的2017年新美大应用典型漏洞复盘,还原构造部分漏洞案例源代码,同时收集业界漏洞demo,完成实现30个测试用例,目前支持springmvc+freemarker+mybatis的架构方式,力求尽量展示漏洞原理和场景,涵盖对xss、jstl、任意文件上传下载、文件包含、sql注入、spring表达式、命令执行、反序列化、ssrf、目录遍历、xxe、高危函数引用的多项测试案例。希冀通过这样的门槛用例评价coverity及其他开源代码分析软件的使用效果,达到查漏补缺的数据支持,实现“拿来主义”的效用。

测试源码地址: NA

比对结果展示

  1. coverity

测试方法为通过coverity提交构建任务,在五分钟的轮循环后顺利执行检查。

默认配置检视项目共耗时8 min 30 sec,其中11sec为序列等待,8 min 19 sec为Checking out、build、compile、analysis、commit整个的流程的时间,瓶颈在于平台系统软硬件配置、数据库性能、编译参数的设置。显示效果如下图所示,在安全视图检查出来的问题为0,在质量类检查出5个null类型引用的问题。

经过简单调优,步骤为去除配置错误的—security(只对c、c++项目有效)。–disable-fb(会去除findbugs插件),增加–webapp-security-preview和–webapp-security选项。重新运行后共耗时3 min 56 sec,新增7处安全问题,发现重定向、文件下载、信息泄露等问题。

可以看到效果显著,除此之外可以针对jsp文件编译检查(jsp是一种特殊的java文件,标签库、模板引擎都可以转换为java文件)。总体认为将来的优化依然空间巨大。

  1. shipshape
    测试步骤为使用docker搭建shipshape,填入源码目录即可,centos7环境运行失败,https://github.com/google/shipshape/issues/124,但是考虑到它作为一款集成性的平台,并未有我们可以利用的有效规则,暂不深入。此处记为遗留问题,后续关注。

  2. errorpone
    该工具使用简单,通过maven构建阶段即可check,尚未检测出问题,工具的原理是试用编译器hook的形式,在javac阶段编译,对于java服务器端项目检测能力有限。

  3. infer
    使用infer同样分析源代码,结果为0。

    从原理上说出现这样原因有三:infer用于检测 Android 和 iOS 应用的问题,漏洞检测规则在我司java开发场景中会偏少;二、infer运行时首先是捕获阶段,对原生的javac支持较好,对于maven效果较差。值得一提的是Infer转换源代码OCaml数据结构的中间文件,.cfg 文件包含了代码文件中每个函数或方法的控制流程。.cg 包含了代码文件中定义的函数的调用关系,以及该文件对外部函数的调用关系。 .tenv 包含了代码文件中定义和用到的类型,这种思路值得我们借鉴。第二步为分析函数,如果不关联则停止,那么对于j2ee框架就是完全不支持,难以智能实现。

  4. fireline:360出品的工具同样没能相关安全漏洞,如下图所示

    报告了5项有效的代码规范问题。这款工具同infer的异同一张图可以显示:

    这款工具主要在于移动应用,但是在安全规则方面将规则进行分类整理的思路值得借鉴。

  5. spotbugs 发现三项缺陷,效果不如find-security-bugs显著,不过这是比对项目里支持gui模式的工具。

  6. find-sec-bugs发现六项缺陷,发现四处高位代码漏洞,效果显著。

需要考虑和吸收的功能

通过一系列的试用和体验,逐步可以梳理出来自研静态代码扫描软件思路。开源项目的的普遍趋势:少量支持docker部署方式,开放api,

提供gradle,ant、maven构建方式,少量提供集成于eclipse、idea的插件支持。软件设计之初就针对多语言,希望大而全,专注规则,针对node.js的项目已经有开源工具https://github.com/ajinabraham/NodeJsScan,说明这样的方向还是可期的。

思路和理念

静态代码检测工具涉及的基本流程为:对于一些特征较为明显的可以使用正则规则来直接进行匹配出,比如硬编码密码、错误的配置等,这方面可以直接使用的不少(rasp项目的规则也可以用),正则的效率会是问题。 对于OWASP Top 10的漏洞,通过预先梳理能造成危害的函数,并定位代码中所有出现该危害函数的地方,继而基于Lex(Lexical Analyzer Generator, 词法分析生成器)和Yacc(Yet Another Compiler-Compiler, 编译器代码生成器)将对应源代码解析为AST(Abstract Syntax Tree, 抽象语法树),分析危害函数的入参是否可控来判断是否存在漏洞。通过操作类的字节码返回解释器执行,具体可以使用 asm或者 Javassist技术实现。

此外针对公司目前工具使用的场景,可以着重考虑以下几点:

  1. 支持漏洞范围评估:在发生外部漏洞通告诸如s2、反序列化这样的漏洞,可以通过该平台快速发现涉及的项目和源代码位置,针对性的进行定位和判断。这就需要识别项目各项配置文件,关联发现低版本、高危版本第三方引用,对于exclude的文件需要智能摒弃。

  2. 半自动化:由于人工审计积累了相当多的经验,且对于越权、ssrf、csrf、敏感业务信息泄露的情况,涉及验证较多,应当容许在测试环境中,结合平台的人工参与率,做到不遗漏高危业务操作,定位为“白盒工具,灰盒使用”。

  3. 优先支持框架和典型场景利用:由于公司内部使用多种开发技术,需要细致分析大量git项目,识别java、nodejs项目框架作出规则适配,做到典型api、典型行为、典型监控,在软件运行效率可控的情况下建立丰富的有效规则。

  4. 应用场景:在应用场景方面适用于支持上线、变更、周期扫描,面向对象为安全人员,后期再根据情况考虑做详细的漏洞原理讲解等易用性功能。

  5. 直观性:数据提供dashboard支持,可以结合src漏洞定义标准,对各项漏洞进行统计和数据聚合,直观、甚至预测可以漏洞趋势。

  6. 高效稳定构建:由于采用动态语义分析的技术,需要支持对多种依赖构建方式,目前看至少需要对maven、gradle提供支持。效率方面也需要考虑到目前并未有良好的java语义分析工具(antlr4、javacc、jdt),技术选型和测试需慎重。

validate