目录
前言
数字供应链(DSC)的定义
数字供应链安全的重点内容和风险因素
CI/CD管道的安全目标和可信实体
将数字供应链安全集成到CI/CD管道中
结语
本文字数:7715,阅读时长:19分钟
1.前言
在敏捷开发的模式下,应用程序会通过 DevSecOps 的敏捷软件开发生命周期(SDLC)范式进行开发,并使用持续集成/持续交付(CI/CD)管道的流程。
然而,在软件开发、供应和交付运营中涉及的数字应用、基础设施服务和供应链数据等各种活动中(这些活动共同构成了数字供应链),攻击者可以通过链条中的一个薄弱点,隐蔽地引入攻击载体,对数字供应链进行攻击,继而引发广泛的后果。
日前,美国国家标准与技术研究院(NIST)发布了特别出版物《DevSecOps CI/CD 管道中软件供应链安全的集成策略》 (NIST SP 800-204D)。本文基于此文,引发深入讨论,阐述如何将数字供应链安全保证措施集成到 CI/CD 管道中以保护底层活动完整性,从而确保将源代码带入构建、测试、打包和部署阶段的 CI/CD 管道活动不会受到损害。
2.数字供应链(DSC)的定义
从高层次上讲,软件供应链是创建、转换和评估软件制品质量和政策一致性的一系列步骤的集合。这些步骤通常由使用和消费制品以生成新制品的不同参与者执行。例如,构建步骤使用一系列人工制品作为工具(如编译器和链接器),并消耗人工制品(如源代码)来生成新的人工制品(如编译后的二进制文件)。
我们以往所熟知的软件供应链主要是基于传统软件供应关系,通过资源和开发供应过程将软件产品从供方传递给需方的网链系统。而这样的定义如今已无法适应数字经济时代由于技术创新带来的产品服务、基础设施和供应链数据等供应对象及供应关系的新变化。
因此,数字供应链的概念在软件供应链的基础上应运而生。数字供应链主要由数字应用、基础设施服务、供应链数据三大主要供应对象组成。其中,数字应用包括软件、Web、固件等,基础设施服务是指云服务、IT托管服务等,而供应链数据则包括基础数据和敏感信息。
相较于软件供应链,数字供应链更加明确的指出了基础设施服务和供应链数据代表产品服务在供应活动中发挥的建设作用及重要性。
图 1:在数字供应链步骤中不同要素之间的互动
数字供应链中的大多数活动都会对最终的应用产品产生重大影响。因此,每项活动的安全性对于最终结果的安全性至关重要。在供应链引入、生产链、供应链交付运营的过程中,构建、打包和交付数字应用,重新打包和容器化以及基础设施服务安全上线运营等都是数字供应链的核心范畴。
3.数字供应链安全:重点内容和风险因素
3.1数字供应链安全的重点内容
在研国标《信息安全技术 软件供应链安全要求》明确了软件供应链安全保护目标,分别包括提升软件产品或服务中断供应等风险管理能力、提升供应活动引入的技术安全风险管理能力、提升软件供应链数据安全风险管理能力。
数字供应链安全作为软件供应链安全概念的关键演进,其发展建立在软件供应链安全的基础之上。相比之下,数字供应链安全涉及的保护范围更广,保护对象的内涵更加丰富。数字供应链安全的重点内容包括:
- 数字应用安全:围绕数字应用的开发全流程与上线运营整体阶段,包含应用安全开发(DevSecOps/SDL)、开源治理(合规/风险)和数字免疫(防御左移,代码疫苗)。
- 基础设施服务安全:包含云原生安全(CNAPP)和供应链环境安全。
- 供应链数据安全:包含API安全和应用数据安全。
3.2数字供应链中的风险因素
数字供应链的风险因素通常包括:
- 开发环境中的漏洞:开发环境对数字供应链的安全性构成了根本性的风险,不应将其作为构建流程的一部分加以信任。成熟的 SDLC 流程只有在代码审查和扫描程序到位后,才会将代码和资产纳入其软件配置管理 (SCM) 主线和版本分支。
- 威胁参与方:一般是寻求以特权方式访问数字供应链的外部攻击者,或心怀不满、制造内部威胁的员工或供应商;非恶意的威胁参与方也可能影响供应链的安全,如软件工程师由于缺乏工具或为了方便使用而故意隐瞒,导致机密管理不善。
- 攻击向量:包括恶意软件、代码重用(代码级别的引入)、依赖库和依赖组件的引入、社会工程学、网络攻击、物理攻击等。
- 攻击目标(即资产):包括源代码、凭证、敏感信息,如个人身份信息 (PII)、受保护健康信息 (PHI)、知识产权 (IP)、加密材料(如软件成品签名密钥)和专有信息等。
- 利用类型:入侵行为通常包括在数字供应链中注入易受攻击或恶意的依赖项、可访问其他系统的被盗凭证、将恶意代码或漏洞代码注入资源库、通过提交合并请求窃取机密等。
4.CI/CD 管道的安全目标和可信实体
在 CI/CD 流水线中,实现数字供应链安全的一个共同方法是生成尽可能多的出处数据。出处数据与系统或系统组件的起源、开发、所有权、位置和更改的时间顺序相关联,包括促成这些更改或修改的人员和流程。在生成这些数据的同时,还应有相应的机制对其进行验证、认证,并在决策中加以利用。
总的来说,CI/CD 管道需要添加的安全保证措施:
- 在开发和部署第一方软件时采用的数字供应链内部安全做法;
- 在采购、集成和部署第三方软件(即开源和商业软件模块)时采用的安全做法。
4.1 CI/CD 管道的安全目标
在 CI/CD 管道中应用数字供应链安全措施或实践有两个安全目标:
- 积极维护 CI/CD 管道和构建流程。
- 确保上游源头和制品(如资源库)的完整性。
最常见的方法是在 CI/CD 平台中引入安全措施,使开发人员能够自动构建、测试和部署管道。
4.2 CI/CD 管道中需要信任的实体
零信任架构侧重于保护硬件系统(如服务器)、服务和应用程序本身等资源。访问这些资产的实体(如用户、服务和其他服务器)本身并不值得信任,零信任架构的主要目标就是建立这种信任。
在 CI/CD 管道中,信任的范围要大得多,至少需要以下步骤:
- 参与执行各种数字供应链活动(如供应链引入、生产链、供应链交付运营)的实体应通过验证凭证进行身份验证。在认证的基础上,根据企业业务政策,通过一个称为授权的过程,为这些实体分配适当的权限或访问权。
- 应通过验证与之相关的数字签名来确保人工制品及其存储库的完整性。这种完整性保证产生信任。
- 在整个 CI/CD 系统中,上述信任的建立应该是一个循环往复的过程,因为制品要经过不同的存储库才能最终成为最终产品。
- 每个构建步骤的输入和输出都应经过验证,以确保预期组件或实体执行了正确的步骤。
表 1 举例说明了典型的 CI/CD 管道中需要信任的实体。
制品 |
存储库 |
第一方代码 - 内部 |
软件配置管理 |
第三方代码 - 开放源代码或商业代码 |
语言、容器等人工制品管理器 |
构建 |
构建存储库 |
打包 |
软件包存储库 |
5.将数字供应链安全集成到 CI/CD 管道中
为了概述将数字供应链安全集成到 CI/CD 管道中的策略,有必要了解这两种管道各自的流水线及其总体安全目标。
激活 CI/CD 管道的前提条件如下:
- 加固 CI/CD 执行环境(如虚拟机或 Pod),减少攻击面。
- 为操作各种 CI/CD 管道的人员(如应用程序更新人员、软件包管理员、部署专家)定义角色。
- 确定执行各种任务的细粒度授权,如生成代码并提交到 SCM、生成构建和软件包,以及检查各种制品(如构建和软件包)进出版本库。
- 通过部署适当的工具,实现整个 CI/CD 管道的自动化。CI 和 CD 流水线的驱动工具处于更高的级别,会调用一系列特定功能的工具,如用于从版本库中检出代码、编辑和编译、代码提交和测试的工具,这包括软件成分分析 SCA工具、静态应用安全测试 SAST和动态应用安全测试 DAST等。一般来说,驱动工具或构建控制平面的执行信任度要高于构建等单个功能步骤。
- 为应用程序代码的开发和部署定义 CI/CD 管道活动和相关安全要求;基础设施即代码,包含部署平台的详细信息;策略即代码和配置代码,指定运行时设置(如另一种标记语言 (YAML) 文件)。
5.1 确保 CI 管道中工作流的安全
CI 管道中的流水线主要包括构建操作、版本库(公共和私有)的PULL/PUSH操作、软件更新和代码提交。
用于安全运行 CI 管道的框架的总体安全目标包括:
- 同时支持云原生应用和其他类型应用的能力。
- 符合标准的证据结构,如元数据和数字签名。
- 支持多种硬件和软件平台。
- 支持生成证据的基础设施(例如 SBOM 生成器、数字签名生成器)。
5.1.1. 安全构建
要在构建过程中获得数字供应链安全保证,需要完成以下任务:
1)指定有关构建的政策,包括使用安全隔离平台执行构建并加固构建服务器,用于执行构建的工具,以及执行构建流程的开发人员所需的身份验证/授权。
2)使用代理和策略执行引擎等技术执行这些构建策略。
3)确保同时生成构建认证的证据,以证明在软件交付期间符合安全构建流程。
促进第二项任务的常用技术是将 CI 工具的命令与收集证据的功能结合起来,并最终创建整个 SDLC 的证据跟踪。
第一类证据来自构建系统本身,它应能确认所使用的工具或流程处于隔离环境中。这可提供内部操作保证。第二类应收集的证据包括最终构建制品、文件、库和制品中使用的其他材料以及所有事件的哈希值。然后,由构建框架中不受开发人员控制的可信组件使用数字证书对其进行签名,以创建证书,从而为消费者提供软件质量的可验证证明,使他们能够独立于软件生产者验证该制品的质量,从而为消费者提供保证。在这种情况下,制品是由一系列 CI 流程步骤生成的构建。
就 "同时生成证据 "而言,生成的证据应由信任度或隔离度高于构建本身的流程启用,以防止篡改。此类证据的生成需要在构建过程中进行验证。
构建阶段的认证由以下部分组成:
- 环境认证:涉及 CI 流程发生时的系统清单,一般指运行构建流程的平台。平台的组件(如编译器、解释器)必须经过加固、隔离和安全处理。
- 过程认证:涉及将原始源代码或材料转化为人工制品的计算机程序(如编译器、打包工具)和/或对该软件进行测试的程序(如代码测试工具)。对于只观察 CI 流程的工具来说,有时很难区分哪些数据应填入流程证明,哪些数据应填入材料认证。执行源转换的工具读取的文件可能会影响转换工具的选择,也可能包含在转换本身的输出中。因此,流程证明的填充应被视为 "尽力而为"。
- 材料认证:涉及任何原始数据,可包括配置、源代码和其他数据(如依赖关系)。
- 制品认证:制品是 CI 流程的结果或成果。例如,如果 CI 流程步骤涉及在 C 语言编写的源代码上运行编译器(如 GNU 编译器集 (GCC)),那么生成物就是该源代码的可执行二进制文件。如果该步骤涉及在同一源代码上运行 SAST 工具,则生成物将是 "扫描结果"。生成该制品的步骤可以是最终步骤,也可以是中间步骤。与新生成产品有关的证明属于人工制品证明类别。
与签名证据(即认证)及其存储相关的要求必须包括以下内容:
- 认证必须使用安全密钥进行加密签名。
- 存储位置必须防篡改,并使用强大的访问控制加以保护。
这些认证可用于评估政策合规性。政策是一份签名文件,其中包含了对要验证的制品的要求。该策略可能包括检查参与 CI 流程的每个职能部门是否使用了正确的密钥来生成证明,是否找到了所需的证明,以及是否指定了根据相关元数据评估证明的方法。该策略使核查人员能够在制品生命周期的任何时刻跟踪其合规状态。
上述能力共同提供了以下保证:
- 软件由授权系统按照正确的步骤顺序使用授权工具(如每个步骤的基础设施)构建。
- 没有证据表明存在潜在的篡改或恶意活动。
5.1.2. 对存储库进行安全的PULL-PUSH操作
数字供应链的第一项安全任务是确保源代码开发实践的安全。在 CI/CD 管道中,代码驻留在资源库中,由授权开发人员使用 PULL 操作提取、修改,然后使用 PUSH 操作放回资源库。要授权这些 PULL-PUSH 操作,需要两种形式的检查:
1.授权执行PULL-PUSH操作的开发人员所需的验证类型。开发人员提出的请求必须与其角色(如应用程序更新者、软件包管理器)相符。拥有 "合并审批 "权限的开发人员不能审批自己的合并。
2.代码库中代码的完整性值得信赖,可用于进一步更新。
确保代码库中代码可信度的各种机制包括:
- PULL-PUSH请求1:项目维护者应对推送的变更中涉及的所有制品进行自动检查,如单元测试、衬垫、完整性测试、安全检查等。
- PULL-PUSH请求4:如果源代码管理系统中没有内置保护功能,则需要具有以下功能的外部安全工具:
- 通过检测和修复错误配置、安全漏洞和合规问题,提高源代码管理系统安全性的功能。
- 评估和加强SCM系统安全态势的功能,无论有无策略(如开放策略代理(OPA)),都能评估SCM账户的安全设置,并生成一份包含可行建议的状态报告。
PULL-PUSH请求3:版本库或源代码管理系统(如 GitHub、GitLab)应 a) 在沙箱环境中运行 CI 工作流,不允许访问网络、任何特权访问或读取机密;或 b) 具有内置保护功能,可延迟 CI 工作流的运行,直至获得具有写入权限的维护者批准。当外部贡献者向公共版本库提交拉取请求时,这种内置保护就会生效。这种保护的设置应该是最严格的,例如 "要求所有外部合作者批准"[10]。
PULL-PUSH请求2:只有在对工具源代码来源的可信度有信心的情况下,才能使用这些工具运行 CI 流水线。
5.1.3. 软件更新期间证据生成的完整性
软件更新过程通常由一类特殊的软件开发工具执行,该工具被称为软件更新系统。对软件更新系统的威胁主要针对证据生成过程,目的是清除更新的痕迹,阻止确定更新是否合法的能力。
软件更新系统有多种类型:
软件更新系统的主要任务是识别给定更新票据所需的文件,并下载可信文件。乍一看,建立下载文件信任所需的唯一检查似乎就是通过验证与单个文件或软件包相关的元数据上的签名来执行的各种完整性和真实性检查。然而,签名生成过程本身可能会受到已知攻击的影响,因此软件更新系统需要许多与签名生成和验证相关的其他安全措施。
为软件更新系统提供安全保障的不断发展的框架已将其中许多必要的安全措施纳入其规范,并为未来的规范规定了其他一些措施。框架是一套库、文件格式和实用程序,可用于确保新的和现有软件更新系统的安全。框架应通过要求在执行签名操作前满足第 5.1.1 节中定义的策略来保护签名操作。以下是该框架的部分共识目标:
- 该框架应能防范对软件更新系统所执行任务的所有已知攻击,如元数据(哈希值)生成、签名过程、签名密钥管理、执行签名的机构的完整性、密钥验证和签名验证。
- 该框架应提供一种方法,通过支持具有多个密钥和阈值或法定人数信任的角色(旨在使用单个密钥的最低信任角色除外),将密钥泄露的影响降至最低。对使用高危密钥的角色来说,密钥泄露的影响应该是最小的。因此,在线密钥(即以自动方式使用的密钥)不应用于客户最终信任其可能安装的文件的任何角色[11]。当密钥在线使用时,应格外小心保管,例如将其存储在硬件安全模块 (HSM) 中,并且只有在被签名的制品通过第 5.1.1 节中定义的策略时才允许使用。
- 该框架必须足够灵活,以满足各种软件更新系统的需求。
- 该框架必须易于与软件更新系统集成。
5.1.4 安全代码提交
代码提交前应进行适当形式的测试,且必须满足以下要求:
- SAST 和 DAST 工具(涵盖开发中使用的所有语言)应在 CI/CD 管道中运行,并向开发人员和安全人员提供代码覆盖率报告.
- 如果使用开源模块和库,则必须列举、了解和评估依赖关系(通过使用SCA 工具,如源鉴SCA开源威胁管控平台)。此外,还必须测试它们应满足的安全条件。依赖关系文件检测器应检测所有依赖关系,包括传递依赖关系,最好不限制要分析的嵌套依赖关系或传递依赖关系的深度。
代码提交过程中所需的一种安全措施是防止秘密进入提交的代码。这可以通过对秘密的扫描操作来实现,并产生一种称为推送保护的功能。该功能应满足以下要求:
- 提交请求1:(例如,个人访问令牌) 评估已提交代码是否符合组织政策,包括是否存在密钥和应用程序编程接口 (API) 令牌等机密。检测到的秘密应通过安全仪表盘等媒体显著显示,并在检测到违反政策时生成适当的警报,同时记录补救违反政策的方法。
- 提交请求2:分配给管理员的所有版本库都应启用推送保护功能。此类保护应包括开发人员身份/授权验证、强制执行开发人员对代码提交的签名以及文件名验证 。
5.2 确保CD管道中流水线的安全
以下是 CD 过程中应使用的一些尽职调查措施。这些措施可以通过定义允许或不允许部署制品的验证策略来实施。
- 部署请求1:对于已在版本库中并准备部署的代码,应调用安全扫描子功能来检测代码中是否存在密钥和访问令牌等机密。在许多情况下,即使在代码填充之前,也应扫描版本库中是否存在秘密,因为根据版本库的可见性,秘密出现在版本库中可能意味着凭证已经泄露。
- 部署请求2:在合并拉取请求之前,应该可以通过依赖性审查的形式查看任何易受攻击版本的详细信息 。
- 部署请求3:如果已经建立了安全的构建环境和相关流程,那么就应该可以指定部署的制品(即容器镜像)必须是由该构建流程生成的,这样才能允许部署。
- 部署请求4:应该有证据表明容器镜像已进行过漏洞扫描并证明了漏洞发现。漏洞扫描的一个重要因素是运行时间。由于用于扫描制品的工具会不断更新以检测新出现的漏洞,因此与过去的扫描结果相比,最近的扫描结果更有可能是准确的,并能提供更好的保证。这种技术可确保只有经过验证的容器镜像才能进入环境,并在运行期间保持可信,从而使 DevOps 团队能够实施主动的容器安全态势。具体来说,应该可以根据组织定义的策略允许或阻止镜像部署。
- 部署请求5:应定期检查发行版构建脚本是否存在恶意代码。需要执行的具体任务包括:
- 容器镜像一经构建,甚至在推送到注册表之前,就应进行漏洞扫描。早期扫描功能也可以内置到本地流水线中。
- 用于与包含容器镜像和语言包的资源库进行交互的工具应能与CD工具集成,从而使所有活动成为自动CD管道的组成部分。
5.2.1 安全 CD 管道 - GitOps
在 CI/CD 管道中,构建期间和之后的所有操作都涉及与中央存储库(如 Bitbucket、GitHub 和 GitLab)的交互。这些操作统称为 GitOps,是一种由 Argo CD 和 Flux 等开源工具推动的自动化部署流程。GitOps 既适用于基础架构代码,也适用于应用代码,包括提交、分叉、拉取和推送请求。
GitOps 的使用范围如下:
- 将基础设施作为代码进行管理
- 管理和应用群集配置
- 将容器化应用程序及其配置自动部署到分布式系统。
在部署前创建配置数据、捕获与特定版本相关的所有数据、运行期间修改软件以及执行监控操作时,应执行以下数字供应链安全任务:
- GitOps请求1:流程应依靠自动化而非手工操作。例如,应避免手动配置数百个 YAML 文件来回滚 Git 仓库集群上的部署。
- GitOps请求2:为 GitOps 提供便利的软件包管理器应保存已发布软件包的所有数据,包括所有模块的版本号、所有相关配置文件以及其他适合软件运行环境的元数据。
- GitOps请求3:不应在运行时手动应用变更(如 kubectl)。相反,应该对相关代码进行更改,并触发包含这些更改的新版本。这样才能确保 Git 提交始终是集群中运行内容的唯一真实来源。
- GitOps请求4:由于 Git 仓库包含应用程序定义和配置代码,因此应自动提取并与这些配置的指定状态进行比较(即监控和补救漂移)。对于任何偏离指定状态的配置,可执行以下操作:
- 管理员可以选择自动将配置重新同步到定义的状态。
- 应就差异发出通知,并进行人工补救。
5.3 数字供应链CI/CD 管道安全 - 实施策略
如果不对基本业务流程和运营成本造成巨大影响,所有企业都不可能一次性实施数字供应链安全所需的大量步骤。相反,提供数字供应链安全性的解决方案可大致分为以下几类:
- 通过与 DevSecOps 管道中每项任务相关的功能确保数字供应链安全的解决方案:
- 通过确保不被篡改的构建管道来验证软件的正确构建,例如提供对构建过程中使用的依赖关系和步骤的可验证可见性,因为被破坏的依赖关系或构建工具是中毒流水线的最大来源。
- 为交付流水线的每个步骤指定核对清单,以便为实施提供指导,并检查和执行对核对清单遵守情况的控制。
- 通过数字签名和证书确保完整性和出处的解决方案。
- 确保运行代码为最新代码的策略,如制定 "构建期限"(即超过一定期限的代码不应启动),以尽可能使生产过程与软件源中已提交的代码保持一致。
- 保护 CI/CD 客户端,防止恶意代码窃取机密信息(如专有源代码、签名密钥、云凭证)、读取可能包含机密的环境变量,或将数据外泄到敌方控制的远程端点。
6.结语
敏捷开发模式下数字应用以最快速度将代码从IDE或Git存储库带到生产环境中,加快了部署速度,提升了业务系统上线的效率,但数字供应链的安全性对于敏捷开发范式来说同样至关重要,任何一个漏洞都可能造成巨大的损失。
作为数字供应链安全开拓者和DevSecOps敏捷安全领导者,悬镜将持续带来专业的国际化视角,与行业同仁及用户共同探讨交流,践行网络安全社会责任,守护中国数字供应链安全。
参考链接:
https://csrc.nist.gov/pubs/sp/800/204/d/final