何为代码检查服务的门禁级检查
本文分享自华为云社区《代码检查服务三级检查体系中门禁级检查范围介绍》,作者: gentle_zhou。
在日常团队研发过程中,有三个阶段是代码检查服务关注的安全检测点:IDE级检查、MR门禁级检查和版本级检查;分别对应着:在开发人员本地桌面IDE端对本地代码进行静态扫描,在Merge Reuqest阶段对待合入分支的变更代码文件进行分析,在发布阶段对待发布主干或分支的全量代码文件进行扫描。
IDE级检查的特点是快速且准确,版本级检查的特点则是需要扫描的尽量全面,这两者的特性在研发团队看来都是定位比较准确的。但是,对于处在中间阶段的MR门禁级检查来说,定位就略显“尴尬”;其肩负着辅助研发团队把控好每次变更代码入库审核的职责,特征是务必做到检查快速、精准且扫描范围是增量性的。那随着研发人员对代码检查服务的深入使用,必定会提出的两个诉求:
- 能否将门禁级检查的范围和IDE级检查的范围的保持一致,让检查能力左移保持一致,都做到快速且准确呢?
- 能否将门禁级检查的范围和版本级检查的范围保持一致,尽可能多的在MR门禁阶段就拦截防护住问题,保障问题可以及时清理掉呢?
这两个一眼看矛盾的问题,甚至很有可能是由同一个团队,同一个人提出。但这对于参与过全流程开发的研发人员来说很容易理解,在研发生命周期的不同阶段中,研发团队和个人关注的侧重点也是不同的。比如在前期项目开发过程中,研发人员关注的是本地IDE上的代码以及提交到云端的增量代码;而在项目开发后期,研发人员会更加关注版本级全量代码的质量与安全。
IDE级检查 | 门禁级检查 | 版本级检查 | |
---|---|---|---|
特征 | 快速、准确 | 快速、精准、增量性 | 全面、全量 |
检查周期 | 本地按需 | 代码合入必需 | 版本发布按需或定期扫 |
预期合理时间 | 秒级 | 分钟级或秒级 | 小时级或分钟级 |
那么,面对这两个问题,作为代码检查工具方,该提供怎样的解决方案呢?或则说该如何回答呢?本文尝试做一个简单的分析。
门禁级检查流程介绍
在分析两个问题之前,我们先简单介绍下门禁级检查的流程。
在团队日常研发过程中,必不可少的一个环节就是将本地开发的代码合并到云端代码仓里去;其中涉及到的两个git命令就是git commit
(将本地一个或多个文件内更改的代码提交到本地代码仓)以及git push
(将本地分支的commit 推送到远程仓库的相应分支)。而Merge Request(合并请求)的操作则是请求将一个或多个commit合并到不同的分支里去,它不是git命令,而是GitLab、GitHub这类代码仓托管服务提供的一个功能。通常MR用于将特性分支的代码合并到主分支或则开发分支上。
Merge Request作为一种请求机制,可以处于不同的状态,以确保代码审查和合并过程的透明性和可控性;比如说:已开启、进行中、已关闭、已合并、失败、无法合并等。而MR只要还没有被关闭或则合并处于已结束状态,就可以启动代码检查服务开启门禁级的检查扫描。
门禁级检查范围和IDE级检查范围保持一致?
首先是第一个问题:能否将门禁级检查的范围和IDE级检查的范围的保持一致,让检查能力左移保持一致,都做到快速且准确呢?
要回答这个问题,我们首先就要先了解下安全领域很火的一个概念“安全左移”。所谓“安全左移”,就是一种在软件开发生命周期中尽早集成安全措施的实践,意味着在研发生命周期的早期阶段就开始关注安全问题,而不是等到开发后期或临近发布前才开始安全整改。这种做法可以帮助研发团队尽早地发现和修复安全漏洞,从而降低修复成本。
那在代码检查服务中,相比于版本级全量的扫描,门禁级检查就是一种“安全左移”;而相比于门禁级,IDE级的检查是一种更左的“安全左移”手段。针对本节的问题,是否应该让门禁级和IDE级检查的范围保持一致,就不是简单的YES OR NO了,需要考虑本项目代码检查的侧重点和代码检查工具使用流程的差异,明白安全左移里的左移也并非是无限制、无条件的。
首先要明确的是两种检查的范围是不一致的,IDE级检查的范围是本地的代码,范围不固定,可以是一个文件,一个文件夹甚至是整个项目;而MR门禁级检查的范围则是本次MR提交的增量代码,每次MR检查的范围都是不固定的(可能只有一个commit,或多个commit;每个commit包含的扫描内容也不相同),即待合入分支内变更文件内的代码。不同的扫描范围,就需要挑选不一样的规则才可以产生相对来说更好效果的结果。
其次是两种检查的背后逻辑是不同的,IDE因为是在用户本地,允许用户在无网环境下也可以使用,因此检查扫描的逻辑支持(甚至优先)在本地进行;而MR门禁级检查必定会涉及到将代码提交到云端代码仓,需要在网络环境下进行这个步骤,因此门禁级的代码检查是会在云端进行。而这些未下沉至IDE端的引擎(可能是因为引擎过大,引擎需要较多资源启动等)就会导致两种扫描的结果天然就不相同。
然后就是扫描效率的问题。结合前面一点,因为IDE基本上是在本地进行扫描,受限于本地电脑的性能;而MR门禁级检查则是在云端服务器上进行扫描检查。两者的扫描效率也不尽相同,强行一致的规则会导致在IDE端扫描时长不可控。
因此,门禁级检查范围和IDE级检查范围没有必要强制保持一致,两者无论是检查范围、背后逻辑还是扫描效率都不相同。当然在本地IDE端包含了扫描引擎、规则的前提下,希望节省门禁扫描时间,不是那么在意IDE端扫描时长的前提下,两者保持一致也是可以的。
门禁级检查范围和版本级检查范围保持一致?
接着是第二个问题,能否将门禁级检查的范围和版本级检查的范围保持一致,尽可能多的在MR门禁阶段就拦截防护住问题,保障问题可以及时清理掉呢?
我们还是从3个角度来思考这个问题:检查范围,扫描效率和分析精确度。
首先是检查范围,MR门禁级扫描的范围是本次MR提交的增量代码,而版本级扫描的范围则更全,针对的是待发布主干或分支的全量代码文件。两者的扫描范围不在一个层级,一般来说,MR增量扫描的代码量级在几千行上下;版本级因为针对的是整个分支,代码量级在部分开发场景下可能会达到千万行的级别。
其次是扫描效率,MR门禁级检查一般都会有时间限制,每个MR里每次代码检查任务最好控制在分钟级。但每次启用代码检查服务,都是需要一套环节的:申请环境、调度任务、准备环境搭建、下载代码、扫描分析、生成报告等,每个步骤累计下来,整体上看时间就不少。如果再将门禁级检查的范围扩大补充了版本级检查里才覆盖的编译类规则,先不提扫描效果,每次MR门禁级检查的整体时间也将会大幅提升。
第三点则是分析精确度的问题。门禁级检查因为只针对本次MR增量文件,存在信息缺失的情况(比如依赖的头文件、三方件等),在这种情况下,即使规则本身很完善、引擎性能优秀,也会导致扫描准确率下降。再加上部分编译类规则的误报率高,强行左移到门禁级检查,会影响MR合入整体的流程体验(一般来说,每个MR合并会有误报率的把控,大于XX%就会认为未达到误报率要求导致整个MR合入失败)。