在开始使用Fortify做扫描的时候,Build ID这个参数要是没有提前规划好,后面会带来很多麻烦,比如不同分支之间的结果互相覆盖,或者扫描出来的数据莫名其妙串到一块儿去了。想要弄清楚Build ID怎么规划才不会乱,以及一旦重复了要怎么避免结果串线,就得先把Build ID到底是干什么用的给搞明白。在Fortify SCA这套工具里头,翻译阶段会用到【-b
一、Build ID的规划方式
规划Build ID的时候,总的原则是要让它能起到区分项目、能够追溯、并且支持重新复跑的作用。一条比较管用的Build ID,至少得让人能从中看出是哪个项目、哪条分支、哪个模块,以及对应的构建编号或者提交记录。
1、起名字的时候,建议按照产品和模块来组合,比如说写成pay_service_auth_release_20260527_018这样,包含产品名、模块名、分支名和构建号。最好不要让所有的模块共用同一个Build ID,尤其是在微服务、多仓库或者多语言的项目里面,一定要把模块之间的界限写清楚。
2、同时还要把分支和流水线的差异给区分开,像main、release、hotfix、feature这些不同分支,也别去共用一个Build ID。在持续集成环境里,完全可以用环境变量来拼接,比如把项目名、分支名、构建号、短commit id这些信息组合在一起,这样一来,哪怕同一天跑了好多次扫描,每次也都能对应到具体的代码版本上。
3、另外还要注意控制一下Build ID的长度和使用的字符,别把它写得太长,也不要用空格、中文或者别的特殊符号,尽量只使用英文、数字、下划线或者短横线。官方的属性文档里面也提到过,当Build ID的长度超过250个字符的时候,会有相关的配置项对它进行缩短处理,所以在实际规划的时候,就不应该把Build ID写得过于长了。并且最好把这些命名规则都固化到流水线的脚本里面去,不要让开发人员每次都手工去输入,像Jenkins、GitLab CI、Azure DevOps这些工具里面,都应该统一去生成Build ID,并且在翻译、扫描和输出FPR文件的时候都用同一套ID,避免因为前后的参数不一致而带来问题。
二、怎样避免Build ID重复造成的结果串线
当Build ID出现重复的时候,最容易引发的问题,就是本次扫描的时候读到了上一次翻译残留下来的中间文件,或者把两个分支的文件都加到了同一个构建上下文里面去。OpenText SAST的文档里面也说明了,后面再去调用sourceanalyzer的时候,它会把新指定的那些源文件或者配置文件,继续追加到这个Build ID所关联的文件列表里面,这其实也正是结果串线的根源所在。
1、为了避免这种情况,每次完整扫描之前,都应该先做一遍清理的操作,也就是执行sourceanalyzer-b build_id-clean这条命令,然后再去执行翻译和扫描,按照先clean、再translate、最后scan的顺序来。官方的用户指南里给出的示例,也基本上是采用这种顺序,这样就能防止旧的中间文件继续参与到这一次的扫描里面来。
2、并且也要注意不要让多个任务在并发的情况下共用同一个Build ID,在同一台扫描机器上,如果两个持续集成的任务同时用了一样的Build ID,就会相互之间造成干扰。所以在并发扫描的时候,要让Build ID带上流水线的运行号或者是commit id,保证每一个任务都是独立开的。
3、除了Build ID本身,FPR文件的名字也要同步做好区分,不要只改了Build ID,最后却还是把所有结果都输出成一个叫result.fpr的文件。FPR文件同样建议采用同一套命名规则,比如用pay_service_auth_release_018.fpr这种名字,等到上传到SSC平台的时候,再把它对应到正确的应用版本上面去,这样就能避免扫描这一端虽然没有串线,但是在后面的上传环节又把版本给传错了。
4、如果说有那种需要分多次翻译然后再统一扫描的场景,那么在相同的分支、相同的版本、同一个构建范围里面复用Build ID是合理的,但跨了模块、分支或者日期去复用Build ID,基本上都会增加误判的风险。
三、出现串线以后怎样去排查
如果在扫描结果里面发现了数量异常、文件路径里混进了其他分支的东西、或者问题数量突然出现大幅度的变化,这时候首先应该去查Build ID和中间文件的情况,而不要马上去修改规则集。
1、可以用sourceanalyzer去查看一下当前这个Build ID相关联的文件都有哪些,或者看看翻译阶段有没有出现什么警告信息,确认一下是不是混进了旧的目录、其他模块的代码、测试代码,或者一些已经废弃的路径。要是查到了异常,就先做一次clean操作,然后再重新翻译。
2、还要去核对一下持续集成环境里的日志,检查翻译阶段和扫描阶段所使用的【-b】参数是不是完全一致的,中间有没有因为脚本拼接导致写错了的情况,同时也要看一下工作目录有没有被复用、缓存目录是不是共享的、构建号有没有被写成空的情况。
3、如果上面的步骤还是定位不到问题,就可以重新挑一个全新的Build ID,把工作区清理干净之后,再完整地跑一次流程。要是新的结果恢复正常了,那基本上就能判断出之前的问题,是由于Build ID被重复使用或者中间文件没有清理干净导致的。
4、平时每一次扫描的时候,最好都把Build ID、分支、commit id、FPR文件名、上传的应用版本以及执行的时间这些信息记录下来,这样后面一旦出现结果对不上的状况,就能直接追踪到是哪一次扫描的链路出了问题。
总的说来,要把Build ID规划得不混乱,核心就在于把项目、模块、分支、构建号或者commit id这些信息按照统一的命名规则组合起来,并且让流水线自动去生成它。而想要避免因为Build ID重复所导致的结果串线,关键就是每次完整扫描之前都先执行一次clean,同时要防止不同的任务、不同的分支、不同的模块去共用一个ID。Build ID表面上看起来只是一个小小的参数,可它实际上直接决定了Fortify的翻译结果和扫描结果能不能对得上,把它规划好了以后,不管是后面的结果追溯、上传SSC,还是问题复盘,都会变得稳当很多。