Fortify扫描时内存不足应当怎样处理,以及大型项目的扫描参数又该怎样调整,这是大型项目在接入SAST时很容易碰到的问题。Fortify SCA在扫描的时候,需要经过代码转换和安全分析这两个阶段,项目的代码量越大、依赖越多、语言越复杂,内存方面的压力就会越明显。OpenText的文档也说明了,扫描所需要的物理内存,会受到代码复杂度的影响,在默认情况下,它会根据系统可用的物理内存自动去分配,但遇到OutOfMemory的时候,可以通过-Xmx去调整Java的堆内存,也可以使用SCA_VM_OPTS来统一设置内存的选项。
一、Fortify扫描内存不足怎么办
Fortify扫描出现内存不足的时候,不要只想着把内存参数无限制地往上调。先要确认到底是Java堆内存不够、机器物理内存不够,还是项目扫描的范围过大,导致分析的压力太高了。不同的原因,处理的方式是不一样的,盲目地去加参数,有时候只会让扫描变得更慢,甚至把CI机器给拖垮。
1、先查看错误日志
先要去检查SCA日志当中出现的OutOfMemory、Java heap、GC overhead、native memory、stack overflow这一类的关键词。如果日志里面提示的是Java heap不足,那就可以优先考虑去调整-Xmx;如果是系统的物理内存不足,那就需要去增加机器的资源,或者把扫描拆分开来;如果是因为某些特别复杂的函数,导致分析卡住了,那就要进一步去定位具体的模块,而不是只去改动全局的参数。
2、提高可用的内存
可以适当地去提高sourceanalyzer在运行时的Java堆内存,比如说根据机器的资源情况,去设置-Xmx这个参数。这里需要留意的是,-Xmx的数值不能超过机器实际能够承受的范围。如果CI机器总共只有8GB的内存,却把Fortify的堆内存设得很高,那么操作系统和构建工具也会来争抢资源,反而更容易导致失败。
3、减少无效的扫描内容
在大型项目里面,测试数据、构建缓存、第三方库的源码、生成的代码、前端的打包产物这一些内容,经常会被错误地扫进去。在扫描之前,应当把不需要分析的目录给排除出去,只保留真正需要做安全分析的业务代码,还有必要的依赖。这样做,比单纯去加内存要更加有效。
二、Fortify大型项目扫描参数怎么调整
大型项目扫描参数的调整,重点在于让扫描的范围、内存、线程还有构建的过程彼此匹配。Fortify并不是跑得越“全”就越好,而是要保证扫描的对象准确、结果稳定,并且CI能够持续地去执行。在做参数调整以前,最好是先把工具的版本和构建脚本固定下来,避免每一次跑出来的结果都不一样。
1、调整内存的参数
在sourceanalyzer命令里面,去设置合适的-Xmx,或者通过SCA_VM_OPTS让内存的配置对所有扫描都生效。这种方式比较适合在CI里面进行统一的管理。比如说,团队可以按照项目的规模,去设置不同的扫描模板,小项目使用比较低的内存,大项目则使用更高的内存,避免所有的项目都去共用同一套参数。OpenText的文档里面也提到过,SCA_VM_OPTS可以用来给所有的扫描设置相关的内存分配选项。
2、把扫描的范围拆分开来
如果单次扫描仍然出现内存不足,那就可以按照模块、服务,或者语言去进行拆分。比如说,先分开扫描后端的服务、前端的工程、公共库还有独立的组件,然后再按照项目的要求,把结果汇总起来。在拆分扫描的时候,要注意边界的问题,不要把关键的调用链拆得过于零碎,否则就有可能会影响到跨模块的数据流分析。
3、控制并行处理和CI的资源
CI里面如果同时跑着编译、测试、依赖下载,还有Fortify扫描,资源上的竞争就会非常明显。对于大型项目,可以把Fortify放到独立的节点上面,或者去限制同一台机器上的并发任务数量。比起单独去调高扫描的内存,保证扫描过程当中有稳定的CPU和内存资源,是更加重要的一件事情。
三、Fortify扫描稳定后还要检查什么
内存方面的问题解决以后,并不代表扫描的质量就一定变好了。还需要去确认扫描的对象是不是完整的、报告是不是正常生成了、规则是不是符合项目的要求。如果为了节省内存,把重要的源码给排除出去了,那么扫描虽然成功了,但结果的价值是会下降的。
1、核对扫描的范围
去检查扫描日志里面的文件数量、语言的类型,还有被排除的目录,确认关键的业务代码没有被错误地排除出去。尤其是在多语言的项目里面,要确认Java、JavaScript、C#、Python这些主要的代码,都已经被正确地识别到了。
2、保留参数变更的记录
建议在扫描配置记录里面,写清楚工具的版本、-Xmx的设置、扫描的目录、排除的规则、CI节点的配置,还有调整的原因。这样一来,后续扫描结果出现变化的时候,团队就能够判断,这到底是代码变化造成的,还是扫描参数变化造成的。没有记录下来的参数调整,后面是很难去排查的。
3、建立大型项目的扫描模板
对于同类型的项目,可以去沉淀出一套标准的模板,里面包括构建的命令、转换的命令、分析的命令、内存的配置,还有排除的规则。这样新的项目在接入的时候,就不需要反反复复地去试错了,也能减少因为个人脚本上的差异,而导致的扫描失败。
总结
Fortify扫描内存不足怎么办,以及大型项目的扫描参数怎么调整,它的核心是先去看日志,判断内存不足的类型,然后再从内存的参数、扫描的范围和CI的资源这三个方面去入手处理。可以适当地去调整-Xmx或者SCA_VM_OPTS,但是不要只依靠增加内存,去解决所有的问题。大型项目更是需要去排除无效的目录、拆分扫描的范围、固定CI的资源,还有保留配置的记录。这样去做,Fortify的扫描才既能够顺利地跑起来,也能够保证结果有实际的参考价值。