8.2 软件验证

NIST 网络行政命令第 4 部分指南的另一个关键组成部分是发布指南,为供应商测试其源代码推荐最低标准。它包括手动和自动测试,例如代码审查工具、静态应用程序安全测试 (SAST)、动态应用程序安全测试 (DAST) 和渗透测试。与行政命令第 4 部分指南中的其他部分非常相似,NIST 采取了从社区收集立场文件 (www.nist.gov/itl/executive-order-improving-nations-cybersecurity/enhancing-software supply-chain-security) 和举办研讨会 (www.nist.gov/itl/executive-order-improving-nations-cybersecurity/enhancing-software-supply-chain-security) 的方法。

在深入探讨所提出的验证测试方法的细节之前,值得注意的是,NIST 指出,虽然网络 EO 使用供应商一词来表示测试,但开发人员经常从外部来源获取软件,因此,如果使用来自其他来源的软件,他们也会进行自己的验证。在已发布的指南中,NIST 推荐了 11 种类型的测试和方法以及我们将很快讨论的补充技术(https:// nvlpubs.nist.gov/nistpubs/ir/2021/NIST.IR.8397.pdf)。从高层次上讲,NIST 的指南讨论了确保开发的软件能够按照开发人员的意图运行,同时在整个生命周期中没有漏洞的必要性。获得这种保证涉及各种活动,例如威胁建模、自动化测试 (SAST/DAST)、动态分析、纠正不可接受的错误或发现,以及对任何相关库、包和服务使用类似的技术。虽然上一章涉及商业指导时已经涉及了许多此类活动,但 我们将从 NIST 定义的角度简要介绍这些活动,这些活动与他们的网络安全 EO 指导相关。

威胁建模

NIST 建议在 SDLC 早期使用威胁建模来识别设计级安全问题。您将获得对系统的概念理解和可视化,并开始分析潜在攻击,以及其相关目标和潜在威胁中实现的利用方法。通过威胁建模,组织正在尝试识别潜在威胁、弱点和漏洞,然后定义与这些威胁相一致的缓解计划。NIST 指出国防部 (DoD) DevSecOps 参考架构图(如图 8.2 所示)作为威胁建模如何作为系统开发和规划活动的一部分融入 DevSecOps 方法论的一个例子。
DevSecOps 不是线性活动(例如瀑布),威胁建模也不应该是线性活动。它应该作为频繁和迭代系统和软件交付的一部分来完成。

自动化测试

NIST 在其指南中明确指出,自动化测试可以像脚本一样简单,用于自动化静态分析,也可以像创建整个环境一样复杂和自动化,包括运行测试和验证测试成功。组织可以使用简单的工具来测试支持 Web 的应用程序和字段,也可以使用涉及模块和子系统的更复杂的工具。建议包括自动验证,以确保静态分析不会报告新的弱点,测试以迭代方式运行,结果准确,并且使用自动化可以减少对人工分析和工作量的需求,而人工分析和工作量既耗费资源又容易出错。使用 Git 和 CI/CD 管道等现代开发系统的组织可以使验证过程在提交和拉取请求时自动化和可重复

基于代码或静态分析和动态测试

NIST 区分了两种方法:基于代码或静态分析和基于执行的测试,它们分别提供了 SAST 和 DAST 等示例。基于代码的静态分析推理以原生格式编写的代码,而动态分析涉及基于执行的动态测试和分析,这需要程序执行。与前面提到的用于自动化测试的 DevSecOps 方法一样,NIST 建议在编写代码后立即以迭代小块的形式进行静态代码分析。这种方法比等待对最终产品执行 SAST 更有效,因为可以在 SDLC 中尽早解决缺陷和漏洞

评论硬解码密码

NIST 建议使用启发式工具查找应用程序代码中的硬编码密码。这些密码可能涉及凭证、加密密钥、API 密钥和访问令牌等。由于 API、令牌和凭证的广泛使用,这在云原生环境中尤其具有挑战性,本书的一位作者在一篇题为 "在 DevSecOps 云原生世界中保守秘密"(www.csoonline.com/article/3655688/keeping-secrets-in-a-devsecops-cloud-native-world.html)的文章中谈到了这个话题。研究表明,相当一部分数据泄露事件都与凭证泄露有关,因此企业应加强机密管理能力,以消除这些风险。

通过语言提供的检查和保护运行

在指南中,NIST 还建议使用各种编程语言(包括编译型和解释型)提供的预构建检查。NIST 还强调,有些语言不具备内存安全性,即防止程序员引入与应用程序中内存使用方式相关的特定类型的错误,并建议强制执行内存安全性。除了使用内置的强制执行功能外,企业还可以使用静态分析器或 "精简器 "等措施来查找危险的函数和参数。值得注意的是,其他指南(如上一章讨论的 OpenSSF 开源安全动员计划)也建议业界转向内存安全语言,摒弃与内存安全相关的固有风险增加的传统语言。

黑盒测试用例

与前面讨论过的测试类型不同,黑盒测试并不与特定的代码片段挂钩,而是侧重于功能需求,并验证软件不应该做什么。这些测试包括拒绝服务和输入边界等内容,在进行测试时不需要源代码分析和威胁建模所需的内部知识和假设。

历史测试案例

当 NIST 指南使用 "历史测试用例 "一词时,它指的是通常所说的回归测试。回归测试在成熟的安全团队中非常普遍,他们实施测试来验证先前发现并修复的漏洞是否存在。这种类型的测试非常重要,因为在配置和卫生偏移等情况下,不安全的配置和系统状态可能会再次出现。回归测试有助于验证情况并非如此。

模糊测试

NIST 推荐的另一种软件验证方法是模糊或模糊测试,这是一种自动测试方法,通过向软件中注入无效、畸形或意外输入来识别缺陷和漏洞。一旦这些输入被注入系统,模糊测试工具就会观察系统的反应,如死机或泄露本不应该泄露的信息。开放式全球应用安全项目(OWASP)为希望了解更多信息的用户提供了一个全面的模糊页面,网址是 https://owasp.org/www-community/Fuzzing。

网络应用扫描

网络应用扫描通常被称为动态应用安全测试(DAST)或交互式应用安全测试(IAST),适用于软件提供网络服务的情况。这两种工具执行的活动与模糊测试类似,但它们都是针对网络应用程序执行的,因为它们都在寻找异常或故障。世界上最流行的网络应用扫描工具是 OWASP Zed Attack Proxy (ZAP;(www.zaproxy.org))。

检查随附的软件组件

NIST 最后建议的开发人员测试清单最低标准是检查包含的软件组件。NIST 指出,这项活动的目标是确保所包含的代码至少与本地开发的代码一样安全。正如我们在本书中所讨论的,软件组成分析(SCA)等工具可以帮助识别软件正在使用的开放源码软件库、软件包和依赖项。这些工具可查询漏洞数据库,如 NIST 的国家漏洞数据库 (NVD),以查找这些组件中的已知漏洞。鉴于大多数现代软件都是由开放源码软件组件组成的,因此这项工作尤为重要。 NIST 还提供了有关我们讨论的所有技术的其他背景和补充信息,如果您想了解有关此类测试技术的更多详情以及如何成功实施这些技术,这些信息值得您深入了解。