🐝CICD top 10 Security Risk

前提知识点:

  • 掌握 Gitlab、Jenkins 的相关知识和常用操作

  • 理解 DevOps 的概念

  • 理解 CI/CD 构建流程

云原生应用的DevOps流程图

Top 10 CI/CD Security Risks

流量控制机制不足

风险描述

流量控制机制不足指的是,由于缺乏强制执行额外批准或审查的机制,攻击者已获得CI/CD流程(SCM、CI、工件存储库等)中系统权限,攻击者能够将恶意代码推入管道。

在软件开发的流程中,流量控机制是指对于提交代码和推送更新的审批和控制机制。如果控机制不足,那么攻击者可能会利用这一缺陷,获得系统权限,将恶意代码或工件推送到流水线中,对系统造成损害。

影响

攻击者能够访问SCM、CI或管道下游系统,如果没有额外审查的机制,攻击者会用来部署恶意代码。一旦创建,恶意代码会通过管道一直运送到生产环境。

1. 将代码推送到存储分支,该分支通过管道自动部署到生产中

2. 将代码推送到存储分支,然后手动触发将代码发送到生产的管道中

3. 直接将代码推送到常用的程序库中,该库由生产系统中运行时会调用代码

4. 利用CI中的自动合并规则,该规则自动合并满足预定义需求集的拉取请求,从而推送恶意未查看的代码

5. 利用不完善的分支保护规则,例如,排队特定用户或分支以绕过分支保护并推送恶意代码

6. 以构建环境创建的合法工件的名义将工件上传到工件存储库,例如包或容器。 在这种情况下,缺乏控制或验证可能会导致工件被部署管道拾取并部署到生产中。

7. 访问生产并直接更改应用程序代码,无需任何校验。

案例

在 PHP git 存储库中植入后门。攻击者将未经审查的恶意代码直接推送到 PHP 主分支,最终导致正式的 PHP 版本传播到所有 PHP 网站。

将无关紧要的更改合并到主分支的自动合并规则很容易被绕过,从而允许攻击者将恶意代码合并到项目中。

身份和访问管理不足

风险描述

1. 身份和访问管理不善,会导致用户拥有过多的访问权限,攻击者可以利用这些权限进行攻击。

2. 身份和访问管理不善,会导致权限混乱,难以控制用户对资源的访问。

3. 身份和访问管理不善,会导致用户名和密码泄露,攻击者可以利用这些凭据进行攻击。

影响

软件交付过程由多个系统连接在一起,每个系统提供多种访问和集成方法(用户名和密码、个人访问令牌、SSH密钥等)不同类型的帐户和访问方法可能有自己独特的配置方法,这种复杂性给在整个身份生命周期中管理不同身份以及确保其权限最小化带来了挑战。

CI/CD生态系统中身份和访问管理主要的问题包括:

1. 权限过大的身份

2. 过时的身份

3. 本地身份

4. 外部身份

5. 自注册身份

6. 共享身份

案例

https://www.zdnet.com/article/mercedes-benz-onboard-logic-unit-olu-source-code-leaks-online/

在一个自我维护的面向互联网的 GitLab 服务器可通过自我注册访问后,梅赛德斯奔驰源代码泄露。

https://stackoverflow.blog/2021/01/25/a-deeper-dive-into-our-may-2019-security-incident/

攻击者能够提升他们在环境中的权限,因为新注册的帐户在访问系统时被分配了管理权限。

依赖库滥用

风险描述

根据用户习惯,容易将名字打错为,结果是使用恶意包,或者无意拉取了依赖包但未做检测。

由于预安装脚本在摘取包后立即运行包的代码,因此有些操作不仅是下载了包,还下载后立即执行。

· 名字混淆 - 在公共存储库中与创建类似的名称的恶意包,诱骗客户端下载恶意包。

· 依赖包劫持 - 获取公共存储库维护者的帐号权限,上传恶意代码。

· 建议

· 不允许从不受信任的源地址下载依赖包

· 从外部拉取第三方包时,而不是通过互联网直接获取,而是走代理,由代理去拉取,代理做为安全控制,并在发生安全事件时可以提供对所拉取包的调查能力。

· 在拉取外部包时,应该建立起审查机制。

· 对拉取的包启用校验和验证和签名验证。

· 避免将客户端配置为拉取包的最新版本。首选配置预先审查的版本或版本范围。使用特定于框架的技术将组织所需的包版本持续“锁定”为稳定和安全的版本。

案例

· 恶意包投毒-ruamel包

ruamel.yaml是个处理YAML文件的库,由于习惯性安装:pip install ruamel,缺少了.yaml后缀导致下载了恶意的ruamel包。

· PyPI 官方仓库遭遇request恶意包投毒

https://security.tencent.com/index.php/blog/msg/160

根据用户习惯,在安装requests包,容易将名字打错为 request,结果是使用pip安装成恶意包。

pip install requests --> pip install request

中毒管道执行(PPE)

风险描述

Poisoned Pipeline Execution(PPE)是一种供应链攻击的方法,指的是攻击者利用对源代码管理系统的访问权限,但没有对构建环境的访问权限,来通过向构建流程配置文件中注入恶意代码或命令,从而操纵构建过程,实质上“毒化”了流程,并在构建过程中运行恶意代码

这类风险通常是存在代码仓库中,可控对应的CI管道配置文件,通过修改CI配置文件达到执行对应命令的目的。例如 - Jenkinsfile (Jenkins)、.gitlab-ci.yml (GitLab)、.circleci/config.yml (CircleCI),以及位于 .github/workflows 下的 GitHub Actions YAML 文件。当黑客提交修改申请的时候,管理员配置好的WebHook就会触发对应配置文件,从而执行配置文件中定义的流水线。

而PPE风险具体有三种主要类型组成:

· Direct(D-PPE)【直接】:攻击者修改他们有权访问的代码仓库中的 CI 配置文件(如Jenkins的Jenkinsfile文件),通过直接将更改推送到代码仓库上未受保护的远程分支。由于 CI 管道执行是由“push”或“PR”事件触发WebHook的,并且管道执行的命令是由修改后的 CI 配置文件中的内容定义的,一旦构建管道被恶意篡改,攻击者的恶意命令最终是会在构建节点中运行、触发。

· Indirect(I-PPE)【间接】:如果CI的流水线定义不是在代码仓库中的配置文件定义,而是在CI系统(Jenkins)自身定义的。仍然可以通过代码仓库中存在的文件进行恶意代码执行,如Makefile文件、管道中自定义执行的shell脚本。通过间接插入恶意代码到管道中执行的脚本,达到恶意代码植入。

· Public(P-PPE,or 3PE)【公共】:从公共的代码仓库拉取的代码,如果攻击者通过公共仓库进行投毒,会对CI系统造成破坏,如果CI系统在内网,甚至可能进一步危害内网安全。现在再来看看该题目的解题过程,Jenkins针对该题目有个对应的CI管道,会轮询Gitea地址上的项目,这里需要在Jenkins的系统配置里面改动下目标地址。

基于管道的访问控制不足

风险描述

流水线是 CI/CD 的关键核心。执行流水线的节点执行流水线配置中指定的命令,来进行大量的涉及敏感信息的活动:

· 访问源代码,并进行构建和测试。

· 从不同位置获取机密信息,例如环境变量、保管库、基于云的专用身份服务(例如 AWS 元数据服务)和其他位置。

· 创建、修改和部署工件。

凭据使用管理不善

风险描述

CI/CD环境由多个相互通信和身份验证的系统构建而成,由于凭证存储在上面,因此在保护凭证方面带来了挑战。

· Gitlab存储了大量的凭证

· Jenkins上的凭证

不安全的系统配置

风险描述

CI/CD环境由多个系统组成,而这些系统配置和加固方面的缺陷,会导致被入侵

· 使用过时版本或者缺少重要安全补丁的系统

· 具有过于宽松的网络访问控制

· 系统其它的默认配置不当

代码完整性验证

CI/CD流程由多个步骤组成,每个步骤都会调用很多资源,资源依赖于分布在不同步骤中的多个来源,而这些来源可能会造成不安全的因素,通过这些入口点可以篡改资源

记录和可见性不足

日志记录和可见性风险不足,在任何事件后难以调查

强大的日志记录和可见性功能对于组织准备、检测和调查安全相关事件的能力至关重要。

Last updated