十大 CI/CD 安全风险(一)
CI/CD 环境、流程和系统是现代软件组织的核心。他们将代码从开发工程师的工作站传递到生产环境。结合 DevOps 和微服务架构的兴起,CI/CD 系统和流程重塑了工程生态系统:
-
技术堆栈更加多样化,无论是编码语言,还是流水线中进一步采用的技术和框架(例如 GitOps,K8s)。
-
采用新的语言和框架的速度越来越快,没有重大的技术障碍。
-
自动化和基础设施即代码(IaC)实践的使用有所增加。
-
第三方,无论是外部提供商的形式还是代码中的依赖关系,都已成为任何 CI/CD 生态系统的重要组成部分,新服务的集成通常只需要添加1-2行代码。
以上这些特征允许更快、更灵活和多样化的软件交付。然而,也为攻击者提供了许多新的途径和机会,增加了企业的攻击面。
本系列文章系统整理与 CI/CD 相关攻击媒介进行的广泛研究以及安全漏洞分析结果,帮助企业及其开发团队更好地保护其 CI/CD 生态系统。
流程控制机制不足
流控机制不足(insufficient flow control)指的是由于缺乏强制执行额外批准或审查机制,攻击者在 CD/CD 进程(SCM、CI、Artifact 存储库等)获得系统权限,轻松将恶意代码或工件轻松推送到流水线中的问题。
影响
攻击者获得可以访问 SCM、CI 或流水线下游系统的权限,便能够利用不足的流控机制来部署恶意工件。一旦创建,工件就会通过流水线推送到生产环境且无需任何批准或审查。以下的情况可能出现:
-
将代码推送到存储库分支,该分支会通过流水线自动部署到生产环境。
-
将代码推送到存储库分支,然后手动触发将代码运送到生产环境的流水线。
-
直接将代码推送到实用程序库,供在生产系统中运行的代码使用。
-
滥用 CI 中的自动合并规则,该规则会自动合并满足一组预定义要求的拉取请求,从而推送未经审查的恶意代码。
-
滥用分支保护规则不足。例如,排除特定用户或分支来绕过分支保护,从而推送未经审查的恶意代码。
-
以构建环境创建的合法工件的名义将工件上传到工件存储库,例如包或容器。在这种情况下,缺乏控制或验证可能会导致工件被部署流水线拾取并部署到生产中。
-
访问生产并直接更改应用程序代码或基础设施(例如 AWS Lambda 函数),无需任何额外的批准/验证。
建议
建立强化流水线流控机制,以确保没有任何个人或程序能够在没有外部验证或验证的情况下通过流水线传送敏感代码和工件。企业可以通过实施以下措施来实现:
-
在用于生产和其他敏感系统的托管代码的分支上配置分支保护规则。尽可能避免将用户帐户或分支排除在分支保护规则之外。如果用户帐户被授予将未经审查的代码推送到存储库的权限,务必确保这些帐户无权触发连接到相关存储库的部署流水线。
-
限制自动合并规则的使用,并确保无论在何处使用,要适用于最少量的上下文。彻底检查所有自动合并规则的代码,确保这些不会被绕过,并避免在自动合并过程中导入第三方代码。
-
在适用的情况下,防止帐户在未经额外批准或审查的情况下触发生产构建和部署流水线。
-
只允许工件在由预先批准的 CI 服务帐户创建的条件下在流水线传输。防止通过其他账户上传的工件在没有二次审核和批准的情况下在流水线中推送。
-
检测并防止生产中运行的代码与其 CI/CD 之间的偏差和不一致,并修改任何包含偏差的资源。
身份和访问管理不足
身份和访问管理不足(inadequate identity and access management)的风险源于管理分布在工程生态系统中不同系统(从源代码控制到部署)的大量身份的管理难题。如果身份和访问管理不善,企业受到攻击威胁风险将会大大增加。
软件交付过程由连接在一起的多个系统组成,目的是将代码和工件从开发环境转移到生产环境。每个系统都提供多种访问和集成方法(用户名和密码、个人访问令牌、市场应用程序、oauth 应用程序、插件、SSH 密钥)。不同类型的帐户和访问方法可能具有其独特的配置方法、安全策略集和授权模型。这种复杂性为在整个身份生命周期中管理不同身份以及确保其权限与最小特权原则保持一致带来了巨大挑战。
挑战
在典型环境中,SCM 或 CI 的普通用户帐户是高度宽松的,因为这些系统传统上并不是安全团队的主要关注领域。这些身份主要由需要能够在代码和基础架构中进行重大更改的工程师使用。CI/CD 生态系统中围绕身份和访问管理的一些主要问题和挑战包括:
-
过分宽松的身份 – 在 SCM 中,确保每个用户和应用程序身份仅被授予所需的权限,并且仅针对其需要访问的实际存储库授予权限并非易事。
-
过期的身份 — 不活跃和/或不再需要访问但没有针对所有 CI/CD 系统取消配置的人员和程序帐户的员工/系统。
-
本地身份 — 没有与集中式 IDP 联合访问的系统,创建在相关系统内本地管理的身份。本地帐户在执行一致的安全策略(例如密码策略、锁定策略、MFA)以及正确取消对所有系统的访问权限(例如员工离职)时带来挑战。
-
外部身份
使用非组织拥有或管理的域中的电子邮件地址注册的员工—在这种情况下,这些帐户的安全性高度依赖于分配给他们的外部帐户的安全性。由于这些帐户不由组织管理,因此不一定符合组织的安全策略。
-
外部协作者 — 一旦授予外部协作者对系统的访问权限,系统的安全级别就源自外部协作者的工作环境级别,超出了组织的控制范围。
-
自注册身份 — 在允许自注册的系统中,有效的域地址通常是自注册和访问 CI/CD 系统的唯一先决条件。使用默认/基本权限可能会扩大潜在的攻击面。
-
共享身份 — 在用户/应用程序之间共享的身份,由于多人/应用程序使用统一身份账户,在进行追踪和调查时无法进行有效分辨,导致问责制度失效。
影响
在 CI/CD 生态系统中存在成百上千个身份(人类和程序化身份),加上缺乏强大的身份和访问管理实践,以及过度宽松帐户的普遍使用,导致系统上的任何用户帐户都可以为环境授予强大的功能,并且可以作为进入生产环境的通行证。
建议
-
对工程生态系统内所有系统的所有身份进行持续分析和映射(mapping)。对于每个身份,映射身份提供者、授予的权限级别和实际使用的权限级别。确保分析涵盖所有程序化访问方法。
-
删除环境中不同系统中每个身份的持续工作不需要的权限。
-
确定禁用/删除陈旧帐户的可接受期限,并禁用/删除任何超过预定不活动期的身份。
-
避免创建本地用户帐户,使用集中式组织组件 (IdP) 创建和管理身份。每当使用本地用户帐户时,请确保禁用/删除不再需要访问的帐户,并确保所有现有帐户的安全策略与组织的策略相匹配。
-
持续映射所有外部协作人员,确保他们的身份符合最小特权原则。尽可能为人工帐户和程序帐户授予具有预定到期日期的权限,并在工作完成后禁用其帐户。
-
防止员工针对 SCM、CI 或任何其他 CI/CD 平台使用他们的个人电子邮件地址或属于非组织拥有和管理的域的任何地址。持续监控不同系统中的非域地址,并及时删除不合规用户。
-
不允许用户自行注册,并根据需要授予权限。
-
避免将系统中的基本权限授予所有用户以及自动分配用户帐户的大型群组。
-
避免使用共享帐户。为每个特定上下文创建专用帐户,并授予相关上下文所需的确切权限集。