在SDLC中使用静态代码分析的最佳实践(二) – 作者:nightmarelee

欢迎关注微信公众号《白盒研修院》或专栏《SAST白盒审计之路》,那里我会把自己关于SAST所思所想第一时间与大家分析。

6.1 语言的支持

为你的组织选择SAST解决方案时,最重要的问题可能是它是否支持开发团队使用的所有编程语言和平台。例如,如果你的组织开发了一个Android应用程序,那么具有Android API的静态分析器要优于仅支持 C/C++ 和 Java 的静态分析器。你还需要询问该工具支持编程语言的时间,这可以指示成熟度,以及供应商是否对语言语法的特性以及标准库和API的使用进行了全面建模。

6.2 选择语言和人工代码库

针对代码库的SAST解决方案的初始设置可能会非常麻烦,这些工具可能会很挑剔,需要对各种环境和编译器选项进行仔细的预设置。在完成整个分析工作之前,可能需要尝试几次运行该工具,确保不会遇到无法恢复的解析错误。此外,静态分析工具通常会在构建过程中引入2~10倍的运行时开销。可以理解的是,当SAST工具在一夜之间编译并分析代码后,在凌晨3:00发生故障时,将非常令人沮丧。因此,在SAST评估过程中,应选择少数候选代码库,这些候选代码库必须足够小并通常在30分钟或更短时间内完成编译。这样,你可以调整工具设置,并逐步实现理想的配置,而无需在运行时等待数小时或数天。候选代码库应该能够代表总体代码库,这将使你对SAST解决方案的功能有最佳的了解,因为不同的软件产品将具有独特且有趣的缺陷配置文件。除了分析原生代码(nature code)之外,你还应该考虑分析分析测试代码。Juliet测试套件(https://samate.nist.gov/SARD/testsuite.php)是一个很好的选择,该套件由软件保障度量和工具评估(SAMATE)项目创建,部分由NIST赞助。丰田汽车信息技术中心(ITC)的研究人员针对基准SAST工具发布了类似的一组代码库(https://github.com/regehr/itc-benchmarks)。这两个测试套件一起,包含数百个精心设计以展示各种缺陷的微型C/C++和Java程序。通过扫描原生代码和测试代码,你将准确了解SAST解决方案的整体检测功能。

6.3 开发系统支持

通常,SAST解决方案的成熟度依赖于它与软件开发过程的集成程度,最完善的解决方案是提供各种集成选项,以及如何灵活的在内部部署该工具。一些解决方案与桌面IDE(集成开发环境)集成,并在编译错误的时候输出警告,而其他解决方案则部署到构建环境、集成系统或托管服务。为组织选择SAST解决方案时,最重要的是该工具是否支持用于创建和交付各种软件产品的开发环境,这包括编译器、构建系统、IDE、持续集成系统、代码审计系统、版本控制和漏洞追踪器。对这些系统和工具的广泛支持将使你在整个开发过程中透明地集成SAST,以支持成熟的安全开发生命周期。在计划SAST部署时,还必须切实了解DecOps团队的能力,许多SAST和DecOps工具具有丰富的API,但是你的团队是否有技能和时间通过自定义脚本将他们组合在一起,在整个SAST部署过程中,你必须仔细决定是自己构建集成还是寻求独立的建议和支持。

6.3.1 编译与构建系统

一些静态分析工具能够方便地监视构建过程,并监视编译器和链接器的调用。在许多情况下,可以通过在构建命令前加上SAST前缀来设置,例如“SastWrapper make <target>”,这样可以轻松消除启动服务所需的许多初始配置,因此你可以更快地查看分析结果。当然,只有在SAST工具能够识别你的构建环境和编译器的情况下才有可能,通常,这种类型的设置对于重命名的构建系统或编译可执行文件是脆弱的。确保你的编译器和构建系统得到显示的支持是至关重要的,并且当不支持它们时,必须确定是否可以将SAST工具配置为识别其他编译器。通过监视构建过程,SAST工具可以准确查看哪些源文件被编译到目标中,许多大型项目通常都有很多未使用的源文件,因此从分析结果中排除这些文件非常方便。没有工程师愿意花时间对死代码中错误进行分类。除了查看编译的源文件外,SAST工具还可以查看这些文件的编译方式(即,编译器和链接器标志),这非常重要,因为如果SAST工具可以对目标体系结果进行更准确的假设(例如x86与ARM,32位与64位),以产生更好的结果。但是,还应该指出,并非所有SAST解决方案都能够囊括你的构建过程,有些工具需要你自己的构建脚本,这可能会成为维护的噩梦。其他SAST工具在编译器和构建环境方面是完全不知的,他们仅分析位于提供的目录中的所有源文件。这种静态分析工具更可能造成误报,因为他们对于预处理指令及编译时传递的路径不可见。最后,有时SAST工具对支持混合语言版本很有用,如果在你的构建环境中,一次调用“make”将同时编译C和Java代码,则此功能非常有用。许多工具不支持此功能,因此你不得不将Java源文件与C/C++文件分开。修改旧版构建脚本来完成此任务可能非常困难,而且这样做可能会带来维护的问题。

6.3.2 集成开发环境

成熟的SAST解决方案通常会随附用于各种IDE(如Eclipse、Visual Studio、IntelliJ等)的预制插件,这些插件将分析软件工程师本地的更改,并在编译错误时发出警告。这非常方便,因为它鼓励软件工程师将SAST用作日常工作的一部分。这时对开发人员修复代码总是方便的,因为代码开发者心中还是记忆犹新的。商业供应商有时将此功能称为“增量”分析或“快速”分析,它依赖于一种有趣的技术,即中央SAST服务器托管此分析的副产品,或称之为基准。当你在本地分析时,IDE插件将确定由于本地更改而需要重新计算哪些中间产品。然后重新分析这些源文件,并按原样使用其余基线,通常,将本地更改限制在几个源文件中时,将会大大加快分析速度。软件开发人员往往对他们选择的IDE有强烈的选择,你永远无法说服开发人员切换到其他IDE,因为它不支持你正在部署的SAST工具。你选择的SAST工具应支持开发组织最常用的IDE,如果没有,则工具应提供一个API,使你能够创建自己的IDE插件。

6.3.3 持续集成

Scrm/Agile的核心宗旨是使你的开发团队能够快速响应变化,持续集成(CI)系统通常是最有效的敏捷开发模型的一部分,因为当提交中断构建或导致测试失败时,他们会为开发人员提供即时反馈。因此如果你的组织使用CI系统,那么想象将SAST与开发流程集成的方法就很重要。当前的最佳实践是将CI系统用作触发程序,以启动静态分析工具的运行。这样,当开发人员提交违反SAST规则的更改,从而引入新的缺陷时,可以在提交后立即通知他们。成熟的SAST解决方案将提供功能强大的API或命令行界面,从而可以创建这些类型的自动化脚本。您应确保给开发团队适当的时间来开发这些脚本,并习惯于将SAST用作常规开发过程的一部分。一旦SAST工具运行平稳,前期的投入将获得回报。

6.3.4 代码审计系统

SAST还应该与整个组织中的代码审查系统集成,这些系统常见示例包括Gerrit、Code Collaborator和Review Board。你想利用工程师对技术的自豪感,使他们可以轻松地根据同行的意见来发现并修复代码中发现的任何缺陷。将SAST与代码检查系统集成的典型方法是创建一个SAST的新账户,并将该账户设置为发布到服务器的每个代码检查的默认检查者。创建新的代码审阅时,CI触发器应自动启动分析作业,然后,应该建立连接,以允许将SAST代码检查账户从后端SAST服务器中读取相关漏洞,并展示在代码检查系统中。此设置的一个补充是允许SAST账户进行 +1 或 -1 的代码review,具体取决于提出的更改是否能够被完全的修复。当代码review是开发过程的必须部分时,这种类型的系统最有效。主要优点是为开发人员提供了近乎即时的自动反馈,从而减轻了SAST对流程的压力。开发人员无需咨询外部SAST系统即可了解其代码缺陷并进行更改,结果将在代码review工具中呈现到他们面前。但是静态分析有时会非常缓慢,SAST绝对不应该成为代码审查批准流程的卡点,因为开发人员遇到的任何干扰都会削弱该工具的信誉。因此,最好在此阶段仅运行快速而准确的规则集,以确保SAST工具在规定的时间范围内完成分析。很少有SAST解决方案对代码检查系统具有现成的支持,你可能必须提供SAST API或命令行界面自己构建此集成。

6.3.5 日常构建

除了将SAST与你的持续集成和代码审查系统集成外,你还可能希望将SAST与构建系统集成,这是必要的,因为由于独立提交趋向于交互,因此CI系统中运行的SAST不会捕获一些少量的漏洞。可能两个独立的提交都没有缺陷,只有将这些提交组合在一起才能发现漏洞,当然,独立分析变更的CI系统会遗漏此类漏洞,这些漏洞通常被成为“逃逸”漏洞。与代码审查阶段执行的分析(速度是最重要的)不同,构建阶段具有大量的时间,如果针对速度优化了代码检查阶段,则应将构建阶段配置为执行之前禁用的较慢的规则集。请注意,非常大的代码库可能无法在一夜之间完成分析,在这种情况下,你可能考虑到周末进行每周一次分析。当然,此解决方案有一个主要缺点:它生成的结果很少,这使开发人员将SAST与他们的日常工作集成起来更加困难。不管你执行每晚还是每周分析,都应考虑其他加速选项,例如分析作业的并行性。这可以通过将构建过程分成可以快速分析的小型独立组件来实现,但是,如果无法修改内部版本,那么你最后的选择就是投入硬件解决该问题,并调查使用具有大内核和内存的分析服务器。

6.3.6 分布式分析

你必须确保SAST永远不会成为开发过程中的瓶颈,如前所述,一种加速工具的方法是与集成开发或代码review系统集成时禁用慢的规则集,实现此目的的另一种方法是研究动态弹性计算服务的使用。众所周知,软件开发的起伏是很难预测的,但是它对确保SAST服务满足SLA所需的哪种计算基础架构产生了巨大影响。(e.g. 必须在提交后30分钟内分析所有更改,或者每晚分析必须在12小时内完成。)如果你构建基础架构以匹配平均提交负载,那么你的分析将在高峰时间无法满足需求,如果你构建基础架构以匹配负载,则分析服务器将在许多时间处于空闲状态。在多个时区运行的大型软件组织中,这种影响将进一步加剧 – CI服务器上永远没有任何空闲时间。一种解决方案依赖动态弹性计算基础架构。这将需要一个与您的CI系统,每晚构建系统或代码检查系统对话的中央服务器。反过来,该中央服务器将把作业分发出去,使虚拟机进行实际分析。这要求每个VM都具有master分支的副本,以及开发人员的任何部分的提交。并非所有的商业SAST系统都容易支持这种类型的解决方案。您可能需要在这里仔细进行调研。NCC Group建议您进行自己的实验,对平均提交频率和大小进行测量,以确定如何最佳地扩展系统。

6.3.7 漏洞追踪

许多商业SAST工具附带了对常见错误追踪器(如JIRA、Bugzilla)的开箱即用的支持,这些插件可以将漏洞从SAST数据库迁移到自己公司的漏洞追踪器。通常为了方便起见,这样做是为了使开发人员不必学习另一种错误分类系统,在许多情况下,这可以减少开发人员与SAST工具之间的摩擦。在决定是否以及如何将SAST与错误追踪器集成时,务必格外小心,建议不要批量迁移所有漏洞缺陷,因为针对新代码库的第一次静态分析可能会产生数以万计警告,其中许多警告可能是无关紧要的样式问题或误报。这将可能使开发团队不堪重负,如果这样做,很可能会破坏未来成功的可能性。仅当缺陷过于复杂而无法在签入之前解决或在短代码审查窗口范围之内时,才应将缺陷迁移到错误跟踪器。如果设置正确,则在构建中进行的静态分析应捕获这些逃逸的缺陷,并将它们自动记录在错误跟踪器中。

6.3.8 版本控制系统

与版本控制系统集成虽然不是很重要,但仍然是很有用的功能,许多SAST工具可以直接与你的源存储库进行交互,并提取可以补充缺陷报告的数据,例如,在根据受影响的源文件的提交历史记录自动将SAST缺陷分配给特定开发人员时,此功能最为有用。但是,请注意,这种属性的系统依赖于“最佳猜测”的启发式方法,当问题是由代码更改的组合而不是单个更改引起的时候,错误地将缺陷分配给错误的开发人员。如果缺陷分配的准确性非常重要,那么最好避免这种方式与版本控制系统集成。

6.4 分析引擎

在后台,SAST解决方案可以依赖于不同种类的代码或二进制分析技术,范围从类似grep的朴素模式匹配到语法感知的控制流分析,再到能够通过构建抽象语法树追踪有价值数据的数据流分析。每种技术都有自身的优点和缺点,模式匹配可以作为一种快速有效的方法来识别使用被禁止的API函数,数据流虽然往往是静态分析的一种较慢的形式,但可以识别更复杂的过程间的缺陷,这种缺陷需要对变量的值(或值的范围)有特定的了解。单个SAST解决方案中的分析引擎可以利用所有上述技术,因此,应该仔细研究引擎本身,以确保符合组织的需求。你应该检查该工具是否能够检测广泛的漏洞,是否准确,是否可以微调内置规则的敏感度,是否可以一直误报以及是否可以自定义或者扩展引擎以检测全新的漏洞类别。

6.4.1 缺陷类别

首先评估SAST解决方案时,必须仔细研究其内置规则集,需要确认该工具是否支持对常用语言中的各种安全、质量和隐私缺陷问题进行检测。除了保证每种受支持语言的缺陷外,还必须确保分析引擎支持软件产品所有依赖的框架,这在使用框架非常普遍的Web应用程序开发中尤其重要。框架经常会引入体系结构抽象,这些抽象概念可能会使普通的解析器感到困惑,或者鼓励可能会产生意外安全后果的编程模式。SAST工具必须支持这些框架,因为你希望获得影响软件产品的所有缺陷类别的最广泛的覆盖。还应该考虑比较和对比多个SAST解决方案之间的规则集,以便准确地指示典型漏洞的检测支持。

6.4.2 准确度和精度

测试真实的准确性、误报率及漏报率可能是具有挑战性的,但是,在比较多个要购买的SAST解决方案时,了解这些数字至关重要。如前所述,必须注意不要让误报使软件工程师不知所措,同样,需要确保该工具不会忽略重要的安全漏洞。测量误报率是可能的,进行这需要一些努力和时间。你应该将SAST工具指向你的自有代码库,并花一两天时间对报告的缺陷进行分类,无需对所有缺陷进行分类,只需使用该工具报告的每个类别或规则集中的代表性样本即可。完成后,你应该有一个真实和误报的列表,并且能够推断出整个代码库的误报率。通过此练习,还可以了解哪些规则比哪些规则更准确或更不准确。测量漏报率比较困难,因为你无法测量不存在的东西,测量漏报率的一种方法是,将bug跟踪程序中的一系列先前已知的缺陷与通过静态代码分析发现的缺陷进行对比,但是这是一个临时过程,可能会非常耗时,自动化方法将是更理想的。基于这个原因,现在可以看看人工代码库了,先前提到的Juliet和Toyota ITC测试套件经过专门设计,可采用科学、有条理的方法来测量SAST工具的准确性和精密度。该套件包含一组“已知答案”综合测试用例,包括“良好代码”和“缺陷代码”,通过检查SAST工具是否在人工测试套件中检测到缺陷,可以准确表示漏报率,NIST全面描述了进行此类评估的框架。

6.4.3 灵敏度

静态分析引擎是否可以微调对其实用性有很大的影响,成熟的解决方案将允许针对各种规则对检测灵敏度进行调整。通常,这是通过启用其他过程间值跟踪功能,启用错误路径修剪或通过修改统计阈值来实现的。在大多数情况下,更高的准确性会带来分析速度慢的代价,在评估SAST系统以在整个组织中广泛部署时,你将需要牢固地掌握是否以及如何调整引擎的灵敏度。你将需要向下调整,使工具更准确,换句话说,你想以更少的漏报为代价争取更少的误报,这是违反常识的,但是你必须认识到,一般的开发人员将不希望被误报困扰,当你在工程团队中争取较高的参与率时,最重要的是较低的误报率。通过遵循此建议,你将引入更多的漏报,这些漏报不应该遗漏。在典型的质量保证活动中,测试和安全团队将希望以最积极的方式运行SAST工具,以确保在开发中不会遗漏任何关键缺陷,这些团队应该有能力应对更高的误报率。

后文更精彩……

来源:freebuf.com 2020-05-20 00:22:10 by: nightmarelee

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论