使用SLSA框架保障软件供应链安全

本文深入探讨SLSA框架如何通过构建溯源文件验证开源软件构建过程的安全性,详细解析SLSA三个合规等级要求及其防御价值,并介绍PyPI的PEP 740规范实现方案,为开发者和企业提供实用的供应链安全实践指南。

使用SLSA框架保障软件供应链安全

自2020年SolarWinds漏洞事件以来,软件供应链安全一直是热点话题。得益于软件构件供应链层级(SLSA)框架,软件行业正站在可持续解决开源软件安全构建和分发最大挑战的门槛上。

SLSA是一项安全标准,帮助消费者验证开源软件构件的创建过程。其基石是构建溯源文件——由构建平台签署的文件,证明二进制文件、容器镜像或其他文件如何通过项目特定构建流水线从源代码生成。然而,SLSA是相对较新的标准(1.0版于2023年4月发布),要充分发挥其效益,需要多方采纳和实施。除了技术工作外,还需要时间建立认知并推动对符合SLSA工具的需求。

为加速SLSA采用,我们起草了PEP 740规范,为PyPI添加SLSA溯源支持并利用可信发布的力量。但无需等待所有这些工作完全实现即可获得SLSA的益处。继续阅读了解如何利用现有SLSA支持,并帮助在客户和供应商中推广良好的供应链安全实践。

SLSA概述

SLSA 1.0指定了三个不同的合规级别(SLSA构建级别1、2和3),可通过发布适当的构建溯源文件实现。该文件标识构建平台本身(通常是托管的CI/CD平台,如GitHub Actions或Google Cloud Build)以及用于生成最终构建构件的配置参数。对于GitHub Actions构建,溯源文件将标识工作流定义文件、构建的仓库和标签,以及任何其他适用输入(如触发构建的拉取请求ID)。此外,平台应尽最大努力列出项目的所有直接和间接依赖项。

级别1合规性提供构建过程的可视性,以便发现无心之失:溯源文件只需包含上述数据并在可访问位置发布。级别2确保构建溯源文件的真实性,关键要求是溯源文件必须由构建平台签名,且构建必须在专用基础设施上运行。在级别3,额外的构建平台强化防止溯源文件伪造,构建平台必须防止构建过程中用户定义的步骤访问签名密钥,且无论串行还是并行运行,任何两个构建都不能以任何方式相互影响。

如果目标项目达到SLSA级别3合规性,大多数针对构建和分发过程的攻击将面临重大障碍。窃取包上传凭据的攻击者仍需破坏溯源签名密钥才能为其恶意二进制文件或容器镜像伪造有效溯源文件。如果攻击者以某种方式篡改构建过程参数,任何更改都会反映在溯源文件中。(从构建级别2开始,溯源中显示的构建参数必须直接从构建平台读取,而非由调用构建的实体单独提供。)此外,如果将签名溯源上传到具有公共透明日志(如Sigstore)的服务,任何此类攻击都将公开进行,每次被更改的构建都会立即可见。

越来越多的构建平台内置了对SLSA的支持,允许项目通过调用预编写的构建流水线步骤达到级别3。从消费者端,slsa-verifier项目提供可配置工具来验证发布的溯源文件。

最后一步:集成到包生态系统中

所有这些工具已经实现,SLSA的益处似乎触手可及。但还有最后一块拼图:将这些符合SLSA的工具集成到开发人员日常使用的包分发工具中。这最后一步需要包管理系统而非SLSA框架本身范围内的操作决策。例如,下游用户如何知道项目将使用哪些构建平台?项目何时允许在版本之间切换构建平台?某些版本具有签名的级别3溯源而其他版本仅具有级别1溯源是否可以接受?

如果这些问题得不到解答,某些威胁可能会钻空子。假设攻击者窃取了通常提供签名级别3溯源文件的项目的包上传凭据,然后上传具有未签名级别1溯源的构件。消费者如何在这种情况下保护自己?社区需要就处理SLSA级别降级的约定达成一致,最好在包发布和分发工具中自动执行。

这些未解决的问题是SLSA益处尚未完全实现的原因。SLSA工具的参考实现奠定了基础,但需要每个包管理系统来操作该框架,以便消费者不必手动解决歧义。

PEP 740和PyPI中的溯源

现在正是强调进行中的PEP 740的好时机,这是由Trail of Bits工程师William Woodruff和Facundo Tuesca起草的规范草案,旨在为PyPI添加SLSA溯源支持。得益于对可信发布的现有支持,每个包的构建平台本身通过发给每次构建运行的OIDC令牌为PyPI上传提供信任机制。溯源可以通过相同的OIDC令牌使用Sigstore生成无密钥签名,然后将溯源文件与包一起上传到注册表,从而搭便车。这种设计减少了整个系统的攻击面,因此恶意行为者只能通过破坏包源代码或伪造GitHub OIDC令牌向PyPI提交不可信构件。

作为消费者利用SLSA

开发团队无需等待PEP 740和其他包管理器采用类似标准即可逐步获得SLSA的益处。一些包管理器已经内置了下载和验证签名溯源的支持。对于尚未完成集成的软件分发工具,只需稍加努力即可独立调用slsa-verifier。

截至本文撰写时,SLSA支持集成最深入的包生态系统是npm。npmjs.com上每个包的页面总结了最新版本的构建溯源,并链接到相关的Sigstore透明日志。在客户端,npm audit signatures命令将自动验证项目依赖项的所有可用溯源。该命令的输出包括具有已验证构建证明的包数量,但未说明是哪些包。因此,利用npm现有支持的最佳方法是在每次构建或依赖项更新时运行npm audit signatures,并在具有已验证溯源的包数量意外减少时手动审查依赖项列表。

其他包管理器尚未自动定位、下载和验证溯源文件及其签名。许多符合SLSA的项目在其发布资产中托管溯源,编写下载和验证这些文件及其签名的过程脚本非常简单。对于具有大量依赖项的项目,这种手动设置无法很好地扩展。

OCI兼容的容器注册表允许镜像提供者将溯源文件作为构件上传到镜像,但没有标准化方法来将构件指定为溯源文件并自动化验证。某些注册表(如Google Artifact Registry)也使用供应商特定接口下载溯源文件。

我们建议按以下优先级安排SLSA验证工作:

  1. 首先配置容器镜像的验证。实际上,容器镜像依赖项数量不会像软件包依赖项那样快速爆炸式增长,因此验证容器依赖项可以快速产生大量价值。
  2. 实施SLSA检查清单,必须为以二进制文件、容器镜像或其他预构建构件形式分发到构建系统的每个新依赖项完成。如果依赖项发布签名溯源,自动化获取和验证溯源文件的过程。确保每当溯源验证失败时构建失败!
  3. 启动长期工作流,为所有现有依赖项添加溯源验证。对于具有大量依赖项的项目,此步骤将需要最多工作。设定现实的目标日期并以合理的速度处理积压工作。
  4. 向尚未发布SLSA溯源的上游供应商请求SLSA溯源。为SLSA制造一些声音(礼貌地)!让合作伙伴知道您专注于供应链安全,并正在寻找同样关注的供应商。如果有资源,考虑提交自己的拉取请求,为您最关键的依赖项添加SLSA合规性。

迈向安全的软件供应链

与许多安全问题一样,理想的未来状态遵循“设置即忘记”模式:生态系统将深度集成构建溯源,以便包管理器安全工作或根本不工作,无需消费者手动操作。在那一天到来之前,符合SLSA的项目应尽可能清晰地定义其策略,以便用户确切知道期望什么以及何时拒绝构件。具体来说,如果您的项目使用官方SLSA溯源生成器以外的任何东西,请确保消费者知道您的项目使用哪些构建平台,以及他们如何确认签名不仅密码学正确,而且来自正确来源。

最后但同样重要的是,如果您的项目符合SLSA,请在文档中包含验证说明,并将其视为强制性要求。确保您的客户知道,如果他们忘记验证您发布的溯源,他们就跳过了一个关键步骤。向软件供应商和消费者提供教育是实现大规模采用临界质量以解决供应链安全问题的关键。

我们的应用安全团队可以通过审计构建过程(包括构建配置、溯源分发和文档)来帮助您的开源项目,以便消费者可以放心下载和使用您的软件。从消费者端,我们的工程师可以帮助您更新依赖管理流程,从具有现有SLSA支持的供应商中获得最大价值,并为您在更多组织加入时做好准备。如果您感兴趣,请联系我们!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计