您对 CI/CD 管道中实际发生的情况有多少信心?您应该保护的元素以及如何保护

所有文章

CI/CD 管道对于内部到底发生了什么是出了名的不透明。即使您是编写 YAML 配置文件(管道指令列表)的人,您如何确保一切都完全按照描述进行?更糟糕的是,大多数管道都是短暂的,因此即使发生不好的事情,之后也不会留下任何痕迹。

简而言之,管道是一种测试、构建和发布软件、应用程序或工件的自动化方式。这样的管道变得越来越普遍,也越来越复杂。管道非常适合让团队更快地工作,在生成软件工件时提供更一致和可预测的结果。当您考虑到大公司可能拥有数百个相互依赖的精心策划的管道时,自动化这些流程的重要性就变得更加清晰,因此一切顺利且无故障运行至关重要。

作为开发人员和最终用户或客户之间开发过程中的最后一个环节,我认为对于如何将此类自动化流程用作潜在的攻击媒介还没有足够的关注。访问构建管道可能使恶意行为者不仅能够渗透生产公司的系统,而且还可能以影响所有未来用户的方式修改生成的工件,从而创建一个巨大的爆炸半径,通常被描述为 软件供应链攻击.

在上一篇文章中,我们讨论了指导您的原则 保护您的 CI/CD 管道. 在本文中,我将介绍 CI/CD 管道中一些更常见的潜在弱点,并提供一些补救选项。就我们的目的而言,您使用哪种自动化工具或系统并不重要——安全原则仍然有效,您只需要找到合适的工具来保护管道的该部分。 

掌握 CI/CD 的艺术:不可忽视的关键要素

不同的管道具有不同的元素并使用不同的工具。我选择关注的元素几乎与所有管道相关,因此无论您的 SCM、工具或现有安全设置如何,保护这些元素都可以被视为最佳实践。 

秘密管理 – 秘密通常是用于将软件或管道连接到其他资源的字符串或令牌。一个常见的示例是用于将代码连接到 AWS 资源(例如 S3 存储桶)的 API 密钥。大多数人已经知道他们应该隐藏这些秘密,而不是将它们作为纯文本包含在开放存储库中。 CI/CD 管道内部的情况要复杂一些。通常,管道需要访问这些秘密才能访问它们所代表的资源和信息。这意味着任何有权访问您的管道内发生的事情的人都可能会看到并复制您的秘密。即使在管道内部也能保证机密安全的一种方法是使用机密管理工具,例如 Hashicorp 金库。此类工具不仅可以在管道内部混淆您的秘密,而且可以更轻松地轮换您的秘密,以便您可以定期更改它们,从而使从管道中窃取秘密变得毫无价值。无论您选择使用哪种机密管理工具,定期轮换您的机密都可以被认为是一种良好的安全实践。

中毒管道执行 (PPE)  – 中毒管道执行 (PPE) 是一种使威胁行为者能够“中毒”CI 管道的技术,实际上是更改管道指令文件中定义的管道步骤或其顺序。该技术滥用源代码管理 (SCM) 存储库中的权限来操纵构建过程。它允许将恶意代码或命令注入到构建管道配置中,使管道中毒以在构建过程中运行恶意代码。 除非您在每次构建之前验证管道指令文件,否则您很可能对构建不再按照您指定的方式运行这一事实一无所知。即使是微小的变化,例如调用一个库而不是另一个库,也可能产生深远的影响,例如在最终产品中包含后门或加密矿工。 

避免 PPE 的方法之一是验证流水线指令文件是否未被修改。您可以对文件进行加密签名,并将签名验证添加为每个管道的第一步。可用于签名和验证文件的工具是 瓦林特,Scribe Security 发布的工具。无论您最终使用什么签名验证工具,其目的都是确保指令文件的完整性保持不变。  

缓存/依赖项中毒 – CI/CD 管道工作流程经常用于指定必须执行的特定操作。每个工作流程都由一系列一个或多个作业组成,这些作业被描述为一系列操作。出于安全原因,大多数工作流程不共享资源。然而,当需要共享资源时,有一些解决方法。所有工作流都可以平等访问的缓存就是这样的一种解决方法。由于缓存由多个工作流共享,因此只要工作流中发生一次违规,就有权更改缓存,从而使缓存对所有后续工作流使用产生影响。单个 中毒缓存 可能会活跃很长一段时间,影响在该管道中运行的软件构建的无数迭代,因为缓存仅在有新的工件或包要下载时才会更新。

GitHub缓存中毒图片

就像在流水线指令文件的验证中一样,可以使用 瓦林特 签署并稍后验证您的缓存或包含管道所需的所有预先批准的依赖项的文件夹。如果您是偏执类型,那么允许您的管道独立连接到互联网并下载它认为需要的任何库是在您的最终版本中获取更多漏洞和可能的漏洞的可靠方法。  

SSH密钥 – SSH 密钥是 SSH(安全外壳)网络协议的访问凭证。该网络协议用于同一网络上的机器之间的远程通信 不安全的开放网络。 SSH 用于远程文件传输、网络管理和远程操作系统访问。例如,使用 SSH 密钥,您可以连接到 GitHub,而无需在每次访问时提供您的用户名和个人访问令牌。您还可以使用 SSH 密钥来签署提交。您同样可以使用 SSH 密钥将其他应用程序连接到您的 GitHub,例如 到位桶GitLab

为了维护帐户安全,您应该定期检查您的 SSH 密钥列表并撤销/删除任何无效或已被泄露的密钥。对于 GitHub,您可以在以下页面找到 SSH 密钥列表:
使用权 设置 > SSH 和 GPG 密钥

SSH 密钥的图像

一个可以帮助您掌握 SSH 密钥的工具是名为“开源安全态势报告”的工具 吉特加特。如果您配置的任何 SSH 密钥已过期或无效,GitGat 报告将提醒您。除了密切关注您的密钥并经常轮换它们之外,GitHub 还警告说,如果您看到不熟悉的 SSH 密钥,请立即将其删除并联系 GitHub 支持 以获得进一步的帮助。未识别的公钥可能表明可能存在安全漏洞。

SLSA 来源作为不可变的管道日志萨尔瓦多 代表 Software Artifacts 的供应链级别,它是由 Google 和其他行业合作伙伴开发的一个框架,旨在帮助提高软件供应链的安全性和完整性。

SLSA 定义了一组四个级别,每个级别都代表软件供应链中更高级别的信任和保证。每个级别都是安全要求不断增加的增量。一项重要要求是需要文件来源。对于 SLSA 框架, 

出处是有关软件工件的可验证信息,描述了某物在何处、何时以及如何生产的。由于 CI/CD 管道的大部分目的是生成某些内容(通常是构建),因此能够准确跟踪哪些文件进入以及它们发生了什么,是管道的一种不可伪造的机器日志。为此,重要的是 SLSA 来源的创建独立于任何用户。用户可以中断或修改的任何内容的完整性都可能受到怀疑。 

一种允许您在管道中为各种 SCM 系统创建 SLSA 来源的工具是 瓦林特 (是的,Scribe 的同一个工具 - 它是一个非常通用的工具)。该链接将向您展示如何将 Valint 连接到 GitHub 管道,以便为该管道上运行的每个构建生成 SLSA 来源。您稍后可以访问每个来源文件并检查它以查看是否发生了任何异常或意外的情况。以下是此类来源文件的片段:

slsa 的图像来源为

出处文件只是一个 JSON 文件,但由于还没有自动化工具来读取出处文件(目前),读取和解释它们的工作就落到了您的身上。  

确保您的最终结果 – 近年来最著名的软件供应链违规事件之一是 SolarWinds事件。其中,黑客修改了构建服务器中的一些代码,以便该公司发布的每个构建都包含一个秘密后门。另一个著名的破坏最终结果的案例是 2020 年越南政府证书颁发机构 (VGCA) 被黑客攻击,该事件被称为 标志视觉行动。入侵者渗透了 VGCA 网站,并将下载链接重定向到他们自己的、带有恶意软件的软件版本。在这两种情况下,最终用户都无法验证他们获得的软件是否是生产公司打算发布的软件。

一种更简单的攻击可能是将管道末端构建的最终图像替换为恶意图像,并将不良图像上传到需要的任何地方。由于在大多数此类攻击中,图像据称来自生产公司,因此即使该公司受到有效证书的保护也是不够的。这只会使假货更加可信。 

解决方案再次是对管道生成的最终工件进行加密签名,并允许最终用户验证该签名。   

既然我已经提到过 瓦林特 我建议使用开源 Sigstore 的联合签名。 Cosign 旨在通过消除对关键基础设施的需求来简化签名。它允许用户使用其在线验证身份(例如 Google、GitHub、Microsoft 或 AWS)作为密钥。您可以使用 Cosign 来签名和验证映像,使其成为管道最终构建映像的签名和后续验证的理想选择。
无论您选择使用 Valint 还是 Cosign,允许您的用户验证最终工件上的加密签名,以确保他们得到的正是您想要提供的内容,我相信大多数最终用户都会欣赏这个想法。 

未来管道安全

当然,构建管道中还涉及其他元素,这些元素可以从增强的安全性中受益。在本文中,我选择研究一些更明显和一些更容易受到攻击的管道元素。 

无论您使用什么管道工具或基础设施,请务必密切关注违规的可能性。永远不要盲目相信任何告诉您它是完全安全的系统。  

考虑到身份盗窃、鱼叉式网络钓鱼和其他形式的伪造合法访问的威胁日益增加,我们认为签名验证机制是您数字工具箱中的一个很好的多功能工具。
无论您需要签署图像、文件还是文件夹,我邀请您仔细研究 Scribe Security 的 Valint,它是满足此类需求的一站式工具。  

旗帜

此内容由领先的端到端软件供应链安全解决方案提供商 Scribe Security 为您提供 - 为整个软件供应链中的代码工件以及代码开发和交付流程提供最先进的安全性。 了解更多