360Qtest团队 静态代码扫描在 360 无线项目中的实践

simple · 2016年04月06日 · 最后由 Shen 回复于 2021年05月26日 · 8719 次阅读
本帖已被设为精华帖!

前言

其实接到这个任务的时候,我内心是拒绝的,因为据我了解,各种静态代码扫描工具出来已经很长时间了,然而在各大公司推行的情况,相信各位略有耳闻,效果甚微。前阵子我看到 google 上有篇论文,叫《Why Don’t Software Developers Use Static Analysis Tools to Find Bugs?》,我深以为然!结合目前手头推进的经历,以及业务方的各种反馈来看,现实很残酷。但是既然决定做这事了,还是希望能改变这种现状,和 testerhome 的一些牛人讨论过这个话题,非常感谢给我建议的那几位大牛,给了我继续推进这件事的勇气😅 😅。。

-- 感谢何正老师为我们打下的基础

导读

  • 火线的诞生
  • 现有静态扫描工具有哪些?
  • 用户的真实需求和痛点
  • 火线如何与众不同?
  • 火线推广中遇到的困难
  • 火线存在哪些不足

火线的诞生

关注互联网的人也许看到过下面这段代码,当时引起了轩然大波。

事情原由我就不赘述了,我们最初的目的就是从根本上避免这种事在我们这里发生,于是在公司大老板和技术委员会的推动下,出现了一个叫安卓代码红线的工具,也就是火线的前身。

安卓代码红线出现的目的就是杜绝一些明显违反公司规定,或者违反安全类规范的代码内容,希望通过静态代码分析来解决这个问题。前期定下的规则已经大部分实现了(实际上也没几条规则),随着工作的推进,我们发现其实我们可以做更多的事情,于是在安卓代码红线的基础上做了不少扩展,演变成了如今的 “火线” 平台。

火线简介

  • 应用场景:静态代码扫描
  • 前 身:安卓代码红线
  • 扫描引擎:基于 PMD 开源
  • 扫描方式:命令行、GUI、在线扫描
  • 目 标:精确、聚焦、好用、极速

现有静态扫描工具有哪些?

我们针对市面上用的比较多的几个工具进行了分析,大概情况如下(不正确的地方还请指出,谢谢):
(原谅我用图片代替,markdown 表格内换行实在是不会。。。)

上面几种工具的侧重点分别是不同的,从开发的反馈来看,他们用的比较多的是findbugs这个工具,这几款工具的比较相信表格里面已经写的很清楚了,在此不一一讲解。

用户的真实需求和痛点

经过一段时间的调研,我们总结了一些客户的痛点和需求反馈如下:

  • 痛点
    • 假设性问题远远多余实际问题
    • 大型项目扫描的问题数量令人发指
    • 规则无法自定义和扩展,或暂时忽略
    • 环境难安装、配置麻烦、需要上传源代码
    • 结果可读性太差,要么看不懂,要么不知道问题出在哪儿
    • 只能告诉我这里有问题,不能告诉我怎么修改
  • 需求
    • 快速梳理问题,区分优先级
    • 设置好的规则能够在团队内共享
    • 提供数据存储,历史问题跟踪,可评论
    • 提供修复指南,最好能自动修复问题
    • 容易集成到开发环境,比如持续集成,IDE 等,结果实时展示
    • 有纠错和白名单功能,业务特殊需求

火线如何与众不同?

结合上面调研的几种工具,以及火线项目在扫描实际代码的时候总结的一些反馈,我们做了如下实验,新建一个安卓工程,在代码中预留了一些待检测问题,然后分别用不同的工具来扫描,查看结果的命中率,结果大概是这样的:

命中率比较

每个工具的检测结果是不一样的,实际上这个实验也不够严谨,因为 findbugs 和 lint 分别有各自的侧重点和优势,每个工具的特征也比较明显。其中 Findbugs 报了不少"*** doesn't start with an upper case letter"这样的错误,而 PMD 似乎对 R.java 很感兴趣,一下子报了 7000 多个问题(大部分是 R.java 报错),当然规则是可以删减的,我们扫描的时候为了确保完整性没有对规则进行精简。
现在比较流行的 SonarQube 平台就将几种工具集成到一个平台上统一管理和输出,但是在定制化方面较为复杂,规则扩展性和跨平台也不方便,有需求的同学可以去看看这个平台。

报告比较

  • Findbugs

  • Lint

  • PMD

  • 火线


相信通过上面的图片比较,各位应该能看出来我们大致做了哪些事情,我们结合前面提到的痛点和需求来具体看看:

火线在实际项目中的数据(截止 4 月 1 日数据,部分公司数据不做展示)

数据指标 本周数据
累计运行天数 115 天
累计扫描次数 5158 次
覆盖项目及任务 260 个
扫描代码总行数 81,214,988 行
扫描文件总数 215173 个
平均项目扫描时间 38.95 秒
千行扫描时间 0.469 秒

此为 4 月 1 日为止的累计数据,覆盖项目及任务可能存在一个项目多个版本代码的情况

火线已经扫描的项目

常见的问题分布

火线推广中遇到的困难

相信大家在公司内部推广工具或者平台的时候,都会遇到各种困难和阻力,我们也不例外。下面是我们遇到的一部分问题(实际上与人打交道是很困难的)

火线之所以能够获取如此多的珍贵数据样本,其实还是取决于公司流程的保障,正如开头所提到的,有大老板和技术委员会引荐,推动起来会相对容易一些,但是好的产品上是真心能帮人解决问题的,而不是借助于 “尚方宝剑” 来强行推动,站在用户的角度上去帮他们解决问题,才是我们的动力。不过光靠自觉也是干不成事情的,还需要借助公司流程来推行。

公司大流程给我们提供了巨大的帮助:

  • 纳入安全审核流程
  • 接入代码审计流程
  • 提供在线自测平台(我们是没权限获取源代码的)
  • 火线的测试报告作为发布申请的依据
  • 针对业务进行加白和纠错
  • 审计人员做特批处理

目前流程还有待磨合及完善,相信会逐渐产生积极的影响。

火线存在哪些不足

虽然火线借助于公司的流程做了一些工作,但是还远远没有成熟,并且存在的问题也很多,互联网公司的快速迭代开发,让很多细节不再去追溯,很多问题都被忽略,还有一些特殊需求被加入,让代码检测不确定因素越积越多,代码可测性要低于可用性。但是本文并不是讨论如何编写优质的代码,或者如何推动编码规范的,因此在这里就不多吐槽了。

火线目前已经拿到了数百万的缺陷代码样本,能做的事情还很多,目前也存在比较显著的缺点,是我们后面想解决的:

  1. 满足更多业务痛点,空指针、多线程、定制规则实现
  2. 更多安全 SDL 规则的实现
  3. 持续优化,精减无效规则,降低误报率

由于产品现在还不成熟,等足够完善的时候,可以开源出来给各位同行使用,也能帮助产品加速完善和成型。所以目前暂时还不能开源,抱歉哈。。。

共收到 39 条回复 时间 点赞

刚讨论就发帖了,赞效率

纯干货,顶!

这是干货~

#1 楼 @oscarxie 😄 下午一直在写

为啥不做空指针检查呢?

#5 楼 @yuweixx 空指针可以做,但是属于比较糙,和 findbugs 比较的话效果还是不行。只能判断当前类中的变量是否存在空指针,无法判断传参过来的内容是否存在空指针的情况,开发也比较在意这个

写的不错. 好久没写 一上来就要惊艳下啊.
你们的工具原理是什么 是基于 findbugs 封装? 是如何分析语法树抽取规则的?

#7 楼 @seveniruby 其实我经常逛论坛啊,只不过不灌水而已。testerhome 现在流量越来越大了,朋友圈转载也渐渐多起来。之前做的事情都没什么新意,所以没有拿得出手的东西。这次这个东西也是尚未成熟的系统,争取能多吸收 360 在安全方面的优势,把东西开源出去,造福大家。

文中开始提到了,是基于 PMD 的语法树解析来做的,只不过我们结合业务在算法上做了一些调优,规则做了些定制。findbugs 需要编译,我们下一步想把 findbugs 找 NP 的算法吸收进来,解决一个痛点。

好牛啊 这才是 “测试开发” 的工具

simple #15 · 2016年04月06日 Author

感谢加精~~~

很好奇针对 PMD 做了如何调优能让其运行时间简短这么多。。

simple #13 · 2016年04月06日 Author

#12 楼 @m13890 三个策略:

  • 只扫 java 代码
  • 根据业务方反馈,只检查有效规则,精简了很多基础规则
  • 尽可能避免使用 xpath 解析语法树

#13 楼 @simple 有问题想咨询下,在代码分析的时候,是一个代码文件接着一个得扫描检查,还是将代码加载到一起,通过模拟编译来检查。

simple #19 · 2016年04月06日 Author

#14 楼 @m13890 实际上 pmd 是一次性抓取所有符合条件的文件,然后用线程池来批量执行的。通过模式匹配来做的,不需要模拟编译

#15 楼 @simple 我的意思是这样,因为代码文件之间存在互相调用的情况,像这样存在关联的代码文件,因为关联而存在的问题 pmd 是否能检查出来

simple #17 · 2016年04月06日 Author

#16 楼 @m13890 这种问题 pmd 是查不出来的,调用关系无法检测。我们只能定向去检测一些配置项

这东西分析 bug 的效率还是比较高的,但是需要 QA 进行一些初步筛选,否则误报一堆给开发,开发也不会管。QA 有能力进行初步筛选,也是一种能力

19楼 已删除

32 个赞

都没有提及 sonar 貌似此工具也是很不错的啊

话说你是 360 哪个部门的 哈哈哈

#21 楼 @nhy0709 里面提到了 SonarQube 平台。。。

请问火线的基础框架是什么?检测规则的原理是基于源代码还是字节码还是其他?

simple #25 · 2016年04月07日 Author

#24 楼 @lylizzy
火线简介

应用场景:静态代码扫描
前 身:安卓代码红线
扫描引擎:基于 PMD 开源

#8 楼 @simple 期待你们的开源,造福大家哈,楼主

从 0 到有,好羡慕把工具做成了产品的

已拜读

#25 楼 @simple 哈,大兄弟你暴露了姓名和公司邮箱~

simple #30 · 2016年04月08日 Author

#29 楼 @zhangzhao_lenovo 哈,没事儿,之前在这里发过招聘贴,早曝光啦!

坐等开源,这个以后应该也会成为测试的主流工具吧。

* 建议在检查下函数使用,是否使用了不需要使用的钩子函数等,诉求用户进行 1 次系统体检等内容采集所用的函数。是不是说多了。。

还有就是反向检查 上传用户数据那块的,在 360 出安全白皮书之前,故意断了下网,360 打包上传了部分,但来不及销毁在缓存里的,被截取了。

simple #33 · 2016年04月14日 Author

#32 楼 @jiazurongyu 第一个问题可以定向检查,第二个问题是不是需要动态检测?或者说想检查和避免什么样的问题呀?

赞。

之前在公司推 sonar,到现在效果依然不是很好,果断 mark。

simple #38 · 2016年07月20日 Author

#35 楼 @heyt 任重道远😌

#36 楼 @simple 希望能自定义规则

49875183 [该话题已被删除] 中提及了此贴 11月30日 18:36

好文章 mark 以下

非常干货,支持!

请问 fireline 现在不支持 API 调用吗?比如获取扫描结果

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册