十大 CI/CD 安全风险(二)
在上一篇文章中,我们主要介绍了 CI/CD 中流程控制机制不足和身份及访问管理不足两大安全风险,并为企业及其开发团队在缓解相应风险时给出了一些建议。今天我们将继续介绍值得企业高度关注的 CI/CD 安全风险。
依赖链滥用
依赖链滥用(Dependency Chain Abuse)风险是指攻击者滥用与软件开发工作站和构建环境如何获取代码依赖项相关的缺陷,导致恶意程序包在拉取时无意中被提取并在本地执行。
风险描述
随着企业中所有开发环境中涉及的系统数量越来越多,管理自编写代码使用的依赖项和外部包变得愈加复杂。通常使用每种编程语言的专用客户端来获取包,这些包来自自管理的包存储库(例如 Jfrog Artifactory)和特定语言的 SaaS 存储库(例如——Node.js 具有 npm 和 npm 镜像仓库,Python 的 pip 使用 PyPI , 并且 Ruby 的 gems 使用 RubyGems)。
大多数企业能够轻松地检测具有已知漏洞的软件包的使用情况,并对自行编写的代码和第三方代码进行静态分析。但是,在使用依赖项的上下文中,需要一组同样重要的控制来保护依赖项生态系统,包括保护定义如何拉取依赖项的过程。
不充分的配置可能会导致安全意识不强的软件开发人员下载恶意包。在大多数情况下,由于预安装脚本和类似过程旨在在拉取包后立即运行包的代码,因此这个过程不仅下载了包,并且在下载后立即执行包。在这种情况下,主要的攻击向量是:
依赖性混淆——在公共存储库中发布与内部包名称相同的恶意包,试图诱使客户端下载恶意包而非私有包。
依赖劫持——获得对公共存储库包的维护者帐户控制权,来上传广泛使用的包的恶意版本,让用户拉取最新版本的包。
Typosquatting - 发布与流行软件包名称相似的恶意软件包,在开发人员拼错软件包名称时无意中获取名称相似的恶意软件包。
Brandjacking – 以与特定品牌包的命名约定或其他特征一致的方式发布恶意包,利用与品牌的错误关联,试图让开发人员无意获取这些包。
影响
使用上述方式之一将包上传到公共包存储库的攻击者,其目标是在拉取包的主机上执行恶意代码。这可以是开发人员的工作站,也可以是拉取软件包的构建服务器。一旦恶意代码运行,就可以在执行的环境中利用它来窃取凭据和横向移动。另一个潜在的情况是攻击者的恶意代码从构建服务器进入生产环境。在许多情况下,恶意程序包还将继续保持用户期望的原始安全功能,从而降低被发现的可能性。
建议
根据特定于不同语言特定客户端的配置以及内部代理和外部包存储库的使用方式,对应的风险缓解方法在具体执行时会有所不同,不过所有推荐的控制都具有相同的指导原则:
不应允许任何拉取代码包的客户端直接从 Internet 或不受信任的来源获取包。相反,应实施以下控制:
每当从外部存储库中提取第三方包时,请确保通过内部代理而不是直接从 Internet 中提取所有包。在代理层部署额外的安全控制,具备针对被拉取的包的进行安全调查的能力。
在适用的情况下,不允许直接从外部存储库中提取包。将所有客户端配置为从内部存储库中提取包含预先审查的包的包,并建立安全机制来验证和强制执行此客户端配置。
为拉取的包启用校验和验证和签名验证。
避免将客户端配置为拉取最新版本的软件包。首选配置预先审查的版本或版本范围。使用特定于框架的技术将组织所需的包版本持续“锁定”到稳定且安全的版本。
范围:
确保所有私有包都在组织范围内注册。
确保所有引用私有包的代码都使用包的范围。
确保客户端被迫仅从您的内部注册表中获取您组织范围内的包。
当安装脚本作为包安装的一部分执行时,请确保这些脚本存在单独的上下文,该上下文无权访问构建过程中其他阶段可用的机密和其他敏感资源。
确保内部项目始终在项目的代码存储库中包含包管理器的配置文件(例如 NPM 中的 .npmrc),以覆盖在获取包的客户端上可能存在的任何不安全配置。
避免在公共存储库中发布内部项目的名称。
考虑到企业同时使用的包管理器和配置的数量之大,完全防止第三方链滥用(third party chain abuse)并不容易。因此,建议确保对检测、监控和缓解措施给予适当的关注,以确保在发生事故时尽快发现并尽可能减少潜在损害。
基于流水线的访问控制不足
流水线执行节点可以访问执行环境内外的众多资源和系统。在流水线中运行恶意代码时,攻击者利用不足的基于流水线的访问控制(Pipeline-based access control, PBAC)风险滥用授予流水线的权限,以便在 CI/CD 系统内部或外部横向移动。
风险描述
流水线是 CI/CD 的关键核心。执行流水线的节点执行流水线配置中指定的命令,来进行大量的涉及敏感信息的活动:
访问源代码,并进行构建和测试。
从不同位置获取机密信息,例如环境变量、保管库、基于云的专用身份服务(例如 AWS 元数据服务)和其他位置。
创建、修改和部署工件。
PBAC 指的是每个流水线以及该流水线中的每个步骤正在运行的上下文。 鉴于每条流水线的高度敏感和关键性质,必须将每个流水线限制为它需要访问的确切数据和资源集。理想情况下,每个流水线和步骤都应该受到限制,以确保在攻击者能够在流水线上下文中执行恶意代码的情况下,潜在的损害程度最小。PBAC 包括与流水线执行环境相关的众多元素的控制:
在流水线执行环境中访问:对代码、机密、环境变量和其他流水线的访问。
对底层主机和其他流水线节点的权限。
互联网出入口的过滤。
影响
一段能够在流水线执行节点的上下文中运行的恶意代码,拥有其所运行的流水线阶段的完全权限。它可以访问机密、访问底层主机并连接到有问题的流水线的任何系统可以访问。这可能导致机密数据的泄露、CI 环境内的横向移动,可能访问 CI 环境之外的服务器和系统,以及将恶意工件部署到流水线中,甚至生产环境中。攻击者破坏流水线执行节点或将恶意代码注入构建过程的场景的潜在破坏程度,取决于环境中 PBAC 的粒度。
建议
不要将共享节点用于具有不同敏感性级别/需要访问不同资源的流水线。共享节点应仅用于具有相同机密级别的流水线。
确保 CI/CD 系统中使用的机密以允许每个流水线和步骤仅访问其需要的机密的方式限定范围。
在每次流水线执行后将执行节点恢复到其原始状态。
确保运行流水线任务的操作系统用户已按照最小权限原则被授予执行节点的操作系统权限。
CI/CD 流水线任务应在控制器节点上具有有限的权限。在适用的情况下,在单独的专用节点上运行流水线任务。
确保执行节点已适当修补。
确保任务运行环境中的网络分段配置为允许执行节点仅访问其在网络中所需的资源。在可能的情况下,不要授予对互联网的无限制访问以构建节点。
当安装脚本作为包安装的一部分执行时,请确保这些脚本存在单独的上下文,该上下文无权访问构建过程中其他阶段可用的机密和其他敏感资源。
评论