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

本贴最后更新于 2008 天前,其中的信息可能已经东海扬尘

考量点

静态代码审计目前比较好的案例有 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. 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 环境运行失败,Issue #124 · google/shipshape,但是考虑到它作为一款集成性的平台,并未有我们可以利用的有效规则,暂不深入。此处记为遗留问题,后续关注。

  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),技术选型和测试需慎重。

  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    393 引用 • 3380 回帖
  • 代码
    459 引用 • 591 回帖 • 8 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    老哥这个评论框用的是什么啊?