7.4 CNCF的软件供应链最佳实践

在有关软件供应链安全的讨论中经常引用的另一个行业指导来源是 CNCF 的软件供应链最佳实践白皮书 https://github.com/cncf/tag-security/blob/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf)。该白皮书于 2021 年发布,涵盖了保护源代码、物料、管道、工件和部署。它引用了 SolarWinds 事件作为引起人们对软件供应链关注的关键问题,并围绕四个基本原则构建:

■ 供应链中的每一步都必须值得信赖。
■ 供应链中的每一步都必须使用自动化。
■ 必须正确定义和保护构建环境。
■ 供应链环境中的所有实体都必须进行相互身份验证。

白皮书还认识到,不同组织和行业存在各种保证角色和风险偏好。并非所有组织都有相同的保证要求;国防部 (DoD) 运营的武器系统的安全要求比不处理敏感数据的简单 Web 应用程序要严格得多。组织可以根据其特定的风险承受能力和保障要求使用白皮书中的建议来降低软件供应链风险。

白皮书采用了低、中、高三个保证级别。低保证环境是指在开发过程中投入很少时间来保护产品的完整性(或安全性)的环境。中等保证包括合理的保证要求,与大多数部署相一致,并作为本文的基准。最后,高保证环境要求产品不被篡改、抵制未经授权的更改,并采用高保真证明和验证流程。

如图 7.9 所示,白皮书将其与与原材料、产品和制造相关的传统供应链进行了类比。它指出,就像技术如何从精益制造中采用敏捷和 DevOps 实践一样,软件供应链可以利用制造业的洞察力

尽管如此,尽管与制造业供应链有相似之处,白皮书也强调了一些关键差异。首先,现实情况是软件供应链是无形的,包括虚拟和数字组件,这些组件不像物理领域的组件那样可见。其他关键差异包括软件供应链确实并将继续以更快的速度发展,因为它们以技术为中心。最后是重用的存在和数字供应链的复杂性。许多人经常使用短语“一路向下的乌龟”,这意味着在大多数情况下它是一个无限的回归,具有多个级别的直接和传递依赖关系。许多产品和供应链是其他产品或供应链的一部分或组件。这种现实可能会带来一些挑战,特别是因为数据显示大多数漏洞普遍存在于传递依赖关系而非直接依赖关系中,但大多数组织并不了解其传递依赖关系的全部范围。

与物理供应链非常相似,数字和软件驱动供应链中的每一步都有可能引入风险——因此,出现了诸如 SLSA 之类的框架,以及相关的最佳实践,以减轻软件供应链生命周期每一步的风险。与更广泛的网络安全和技术非常相似,软件供应链的强度取决于其最薄弱的环节,因此供应链某一环节的漏洞可能会对供应链的其余部分以及所有下游消费者和利益相关者产生连锁影响,正如我们在供应商和 OSS 组件中多次看到的那样。

CNCF 的指南强调了一些关键主题,例如验证、自动化、受控环境中的授权和安全身份验证。这些主题对于确保整个软件供应链生命周期的强大保证至关重要,并贯穿整个文档的各种建议和推荐控制。

验证是确保从一个阶段到下一个阶段的完整性的关键,而自动化有助于促进可重复和不可变的流程。对机器和人类实体的权限进行适当调整可确保每个实体和阶段只能进行明确定义和要求的活动。虽然这是一种长期存在的安全最佳实践,但这种最不宽松的方法也在行业推动零信任的过程中得到强调,因此在这方面有相似之处。

最后,安全身份验证可确保供应链中实体之间的相互身份验证,使用与环境和所涉及组织的保证级别相一致的身份验证方法。该指南涵盖了供应链的五个阶段——保护源代码、保护材料、保护构建管道、保护工件和保护部署——我们将在以下章节中讨论每个阶段

确保源代码安全

  软件供应链起源于源代码。创建和保护这些源代码是一项基础活动,有可能影响整个下游供应链的完整性。CNCF 的指南指出,身份访问管理 (IAM) 是任何平台或供应商在这方面最关键的攻击媒介,它适用于有权访问源代码存储库的人类和机器实体。Verizon 的 2022 年数据泄露调查报告 (DBIR; www.verizon.com/business/resources/reports/dbir) 等报告证实了这一说法,该报告显示,超过 60% 的数据泄露涉及泄露的凭据。

源代码安全建议涵盖了前面提到的五个主题。这些包括验证活动,例如实施签名提交以确保源提交或修改的完整性和不可否认性。有更传统的方法,例如 GNI 隐私保护 (GPG) 密钥或安全/多用途互联网邮件扩展 (S/MIME) 证书,但也有创新的新兴解决方案,例如 GitSign (https://github.com/sigstore/gitsign),它使用 Sigstore 来促进“无密钥”签名。由于与传统签名和密钥管理活动相关的开销减少,这是一种越来越有吸引力的签名工件和元数据的方法。

自动化还可用于保护源代码和相关存储库。其中一个领域是暴露秘密的问题。在这种情况下,秘密是诸如凭证文件、安全 Shell (SSH) 密钥、访问令牌和应用程序编程接口 (API) 密钥之类的项目。机密蔓延,即敏感凭证的传播和分发,是一个严重的问题,尤其是在包含声明式方法和在各种清单和配置文件中提交机密的机会的云原生 DevSecOps 环境中。

GitGuardian 是一家专注于机密管理的公司,它制作了高度翔实的报告,例如《2022 年机密蔓延状况报告》(www.gitguardian.com/state-of-secrets-sprawl-report-2022),该报告深入探讨了这一问题。一些令人震惊的指标包括 2021 年每位应用程序安全工程师检测到的机密事件超过 3,000 次,2021 年公开暴露的机密超过 600 万个,是 2020 年的两倍。本书的一位作者撰写了一篇文章,介绍了机密管理的现状以及不良做法可能产生的影响(www.csoonline.com/article/3655688/keeping-secrets-in-a-devsecops-cloud-native-world.html)。这些暴露的机密可能会授予恶意行为者的访问权限并在整个环境中造成严重破坏。 GitGuardian 发布的《2023 年机密蔓延状况》报告发现,在公共 GitHub 存储库中暴露了超过 1000 万个新机密,而问题似乎也没有改善。2022 年,机密也以某种形式或方式卷入了安全事件,影响了业内一些最著名的组织,例如 Uber、NVIDIA、Microsoft 和 Slack (www.gitguardian.com/state-of-secrets-sprawl-report-2023)。

为源代码存储库实施受控环境提供了一个机会,可以通过相应的控制来减轻多种风险,包括建立和遵守管理代码贡献的贡献政策。根据先前关于适当调整权限的建议,也有机会协调角色并将权限与组织内的职能职责相关联。组织可以采取更进一步的措施通过使用基于上下文的访问控制机制,检查一天中的时间和设备姿势等因素,以提供动态的、基于时间的访问,这在零信任环境中很常见。网络安全的许多领域经常提出的另一项基本建议是强制职责分离,以便请求的作者不能同时是其批准者。

身份验证是一种帮助授予实体(无论是人还是机器)对源代码存储库的初始访问权限的活动。这里的一些建议包括强制执行 MFA 以访问存储库和使用 SSH 密钥来促进开发人员访问等活动。这些密钥应该有一个相关的轮换策略,以确保如果密钥被泄露,它们在恶意访问和活动方面产生负面影响的能力是有限的。对于机器或服务实体,组织应该采用短期和短暂凭证。这些凭证可以允许机器和服务(例如管道代理)访问,但也可以减轻凭证泄露的影响,因为密钥不断被生成、使用和丢弃。如前所述,被盗用的凭证是恶意行为者最常见的攻击媒介之一,因此使用短期凭证可以减轻这种影响。

确保物料安全

  在软件供应链的背景下,CNCF 的指南将材料作为依赖关系和库进行讨论,无论它们是直接的还是可传递的。这一部分与本书的总体概念密切相关,该概念侧重于软件供应链的透明度和安全性。该指南提到,某些高可靠性环境可能需要仅使用受信任的存储库,同时阻止对其他存储库的访问。值得一提的是,NIST 800-161r1 指南建议建立已知可信组件的内部存储库以供开发使用,我们将在第 8 章“现有和新兴政府指南”中讨论,该指南涵盖了 NIST 的 800-161r1 指南。

  CNCF 指南强调,当涉及到他们正在使用的第二方和第三方软件时,组织应该使用风险管理方法。虽然组织和开源项目都习惯于发布易受攻击代码的常见漏洞和暴露 (CVE),但该指南指出,CVE 也是一个尾随指标,这意味着一旦发现并发布漏洞,它们就会通知消费者;他们使用的代码已经很脆弱。对于组织来说,利用其他指标也很重要,这些指标可以告知使用者与与运营运行状况等指标相关的项目和代码相关的风险。其中一个项目是OpenSSF的记分卡项目,我们将在即将到来的 “OpenSSF记分卡”一节中讨论。

  组织使用来自外部实体的软件组件,因此验证这些第三方库和组件至关重要,包括使用校验和和验证签名等方法。组织还可以(并且应该)使用 SCA 和 SBOM 生成等方法来确定他们正在使用的软件中是否存在任何易受攻击的开源组件。一旦组织使用了 SCA 和 SBOM,他们就可以开始跟踪其使用的 OSS 组件与其所属系统之间的依赖关系,作为其更广泛的软件资产清单工作的一部分。组织可以开始生成供应链清单,该清单不仅包括 OSS 组件,还包括整个组织使用的软件供应商、供应商和来源。

  该指南警告的另一个风险是,恶意代码可能包含在编译软件中,例如二进制文件或压缩包,这些软件是编译的,而不是源代码或文本格式。因此,该指南建议组织从源代码构建其库,而不是使用已编译的软件,因为这些软件可能已被恶意行为者破坏。与创建软件供应链清单的建议非常相似,该指南建议组织拥有受信任的包管理器和存储库的清单,并控制其访问权限,以限制从未经批准的来源引入代码。
  组织还应利用自动化手段来确保从外部获取的材料的安全性。这方面包括扫描软件以发现漏洞、许可影响,并识别与所引入软件相关的直接和传递依赖项。

保护构建管道

  CNCF的SSCP指南将制造业装配线与软件供应链生态系统中的构建流水线进行了类比,甚至将构建流水线称为“软件工厂的核心”。这条流水线汇集了前文讨论过的许多材料,来自诸如源代码控制仓库和第三方提供者等来源。这些构建流水线由多个组件组成,包括构建步骤、工作器、工具和流水线编排器,我们稍后在“安全软件工厂参考架构”章节也将对这些组件进行讨论。
  确保构建流水线的安全性需要加固构建步骤及其相关输出,以确保既不会危害构建流水线本身,也不会危害其过程。恶意行为者知道,如果他们能够入侵构建流水线,他们可以向下游消费者分发恶意软件,而这些消费者可能并不知道上游构建过程已经被入侵。

CNCF 建议采取一些关键步骤来保护构建管道: ■ 使用单个存储库来存储所有构建组件
■ 记录步骤和相关输入/输出
■ 使用签名工件和元数据等方法来确保构建过程的完整性

  组织还应对其构建流水线和基础设施进行威胁建模和自动化安全测试,就像对其他生产系统和环境进行的操作一样。简而言之,从安全的角度来看,您的构建系统应该像生产系统一样对待,因为它们的输出最终会进入运行时环境。如果这些输出受到威胁,生产运行时环境也将受到威胁。
  虽然CNCF的出版物没有具体提到,但关于这个主题的一个优秀的指南来源是新成立的OWASP Top 10 CI/CD安全风险项目。正如该项目所言,CI/CD环境、流程和系统是现代软件交付的核心。该项目指出,滥用CI/CD环境已导致了几起显著的安全事件,如SolarWinds、Codecov等,影响了成千上万的下游消费者和组织(链接:https://owasp.org/www-project-top-10-ci-cd-security-risks)。
  该指南指出了现代构建环境的核心组件,例如流水线编排器、构建工作器以及从安全的工件存储库获取(见图7.10)。这些实体协作执行诸如构建和链接依赖项、构建应用程序、测试并发布到安全存储库等步骤,最终部署应用程序。如果这些过程和实体受到威胁,将对部署环境产生下游影响。
  验证是指南强调的另一个关键活动。这个领域包括使用加密来验证策略的遵从性、在使用前验证环境和依赖关系,以及验证构建工作器的运行时安全性,如图7.10所示。指南提到,产生端到端的加密保证是其中一种选项。
  另一个重点是在高保证和高风险环境中使用可重现构建。简而言之,可重现构建能够使用特定输入生成可以进行加密证明的输出。这意味着可以识别和应对恶意或无意的修改。这种实践在其他指南来源中也有体现,如SLSA所指出的,但众所周知,这并非一项简单的工作,可能在时间和资源上成本高昂。因此,这是一种为高保证环境保留的实践。

其他值得注意的实践和功能包括:

■ 自动创建构建环境
■ 在不同基础设施环境中分发构建
■ 使用自动化来标准化跨团队和项目的管道
■ 配置安全的编排环境以托管软件工厂(请参阅即将到来的部分“CNCF 的安全软件工厂参考架构”

保护工件

  在完成构建阶段后,会生成软件和制品,以及与它们相关联的元数据。为了确保这些制品的完整性,可以采用多种方法进行保护,例如签名。CNCF建议在制品的每个生命周期阶段都进行签名,以确保其完整性。签名是一种通过使用加密密钥对制品进行数字签名的方法,以证明制品在特定时间点由特定实体生成,并且在传输或存储过程中没有被篡改。通过在每个重要阶段对制品进行签名,可以确保制品在整个生命周期内都可以追溯到其源头,并防止未经授权的更改或操纵。
  CNCF的指南建议组织在构建过程中的每个步骤都进行签名,并验证生成的这些签名。他们引用了更新框架(The Update Framework,TUF)、SPIFFE和SPIRE作为可以用来支持整个过程所需证明的项目示例。SPIFFE和SPIRE旨在为现代和异构基础设施提供统一的身份控制平面。SPIFFE和SPIRE的支持包括保护微服务通信、实现安全认证以及用于零信任安全模型的跨服务认证(链接:https://spiffe.io)。通过使用TUF和Notary来自动化管理制品的签名、存储相关元数据和输出,组织可以采纳自动化方法。
  组织还应采取措施限制特定方能够签名的制品,并将这些能力与时间绑定,定期进行审查。时间绑定涉及在凭证和访问有效性上设置时间限制。制品生成后,在分发之前,组织应对其进行加密,并以只有授权平台和消费者能够解密的格式进行加密。遵循这些步骤确保了制品在其各个生命周期阶段内的完整性,并确保最终消费者或接收方(无论是个人还是非个人实体)拥有适当范围的权限和访问控制。这些措施有助于防止未经授权的篡改或访问,从而保护制品的安全性和可信度。

保护部署过程

  在CNCF SSCP白皮书的结尾部分是“Securing Deployments”(保护部署)部分。CNCF再次强调了在这一活动中TUF的重要性,并且有必要能够检测和防止恶意活动。
  验证被提出作为一个关键活动,一旦软件制品被部署,客户端接收到软件制品后可以验证其完整性,还可以验证相关的元数据。这意味着他们可以验证一个软件构建物清单(SBOM)的签名(如果有的话),并验证其是否由授权方签名。