持续集成和持续交付(CI/CD) pipeline是任何以“现代”方式构建软件的软件组织的基础。自动化提供了强大的功能,但大多数开发人员都忽视了它所承担的责任。
开发商:是的,我们接受 CI/CD 安全性 认真对待并严格控制代码维护者,审查 commit合并之前;工作和 pipeline由高级工作人员维护,他们负责不泄露机密 pipelines。而且该工具是由了解该事物的人员安装的。会出什么问题呢?
尊敬的开发者, CI/CD 系统非常复杂。其广泛的攻击面吸引了恶意攻击者。最好保持警惕,不要过度自信。
默认配置有时会被保留,成为黑客最好的朋友。严重缺陷可能存在于 CI/CD pipeline 来源、系统配置,或围绕流程和上下文 pipeline 以及它是如何被触发的。
在这篇文章中,我们将站在坏人的角度。想象一下,我们正在阅读 M3M3N70 (死亡警示?)和 沼泽之怒 在暗网的某个地方,可能使用非西方语言,但千万不要错过,邪恶正在全球蔓延。
在过去的美好时光里,这很容易……
M3M3N70:回到过去的美好时光,我们的业务非常轻松......零日漏洞唾手可得,应用程序完全开放,漏洞易于利用,我们可以快速横向移动。
沼泽之怒: Fu#@Hell !有些人虽然脑子不正常,但情况已经变了。大人物们对 AppSec 投入了大量精力。
M3M3N70:是的。但新的傻瓜是开发人员。对我们来说,使用这些家伙使用的工具更容易。尤其是 CI,这是一个金矿!云访问令牌, SCM 凭证、生产数据库密码、SSH 私钥、其他 CI 用户的凭证……从无聊的开发内容跳到真正的内容相当简单。
使用以下方式实现软件构建、测试和部署的自动化 CI/CD 工具通常需要分步将机密传递给命令。而且它们经常被泄露,造成恶果。
Pipeline需要秘密,但有时会泄露
M3M3N70: The code monkeys slipped their AWS keys in a pipeline on a GitHub commit, later they removed the thing but not changed git history. For our scripts it was trivial to scan the history, grab the key and wreak havoc.
也许美好的时光是在 Git 历史中找到一个 .env 文件(开发人员忘记将其添加到 .gitignore):
AWS_ACCESS_KEY_ID=AKIA...AWS_SECRET_ACCESS_KEY=wJalrXUtn...AWS_REGION=us-east-1APP_FOLDER=...S3BUCKET=...
用于 GitHub 工作流程 .github/deploy.yaml 其中包含如下内容:
jobs:
build:
name: Automated build and deployment into AWS
runs-on: ubuntu-22.04
steps:
# Load environment from .env file
- id: dotenv
uses: falti/dotenv-action@v1.0.2
- name: Configure AWS Credentials
uses:
with:
args: --acl public-read --follow-symlinks --delete
aws-access-key-id: $
aws-secret-access-key: $
aws-region: $
# ... build steps skipped ...
- name: Upload compiled code for deployment
working-directory: $/packaged_app
run: aws s3 cp my-app.zip s3://$
- name: Deploy the app
run: aws deploy create-deployment ...
M3M3N70:哇!这些 aws 密钥正在工作!我们首先测试了应用程序中的无害更改,然后添加了诱捕,因为那些家伙似乎没有意识到。Bingo!真是一场精彩的活动……
恶意行为者只是使用 AWS 密钥上传了带有恶意软件的修改后的应用程序,然后使用此类凭据运行部署命令。泄露的机密以及 pipeline“真是一场恶作剧!”可能意味着 Memento 给可怜的受害者造成了巨大的伤害。
Memento 在这里告诉我们,一旦发生密钥泄露,例如示例中的 AWS 访问密钥,您必须撤销密钥(轮换上述密钥) 立即总是有一个 曝光窗口 泄漏之间 commit 以及秘密无效化; 重写 Git 历史很困难 (即使是最严厉的独裁国家也尝试过这种改写历史的做法,但都无济于事)而且可能无效(我们的朋友可能在秘密泄露的存储库之前就克隆了 commit)。立即轮换密钥,并在暴露窗口期间阅读目标帐户的活动日志并祈祷!
也许组织应该 禁止使用长期秘密 CI/CD pipelines,并将其替换为临时凭证。在上一个 GitHub 操作中使用 AWS 密钥的示例中,使用 OpenID Connect (OIDC) 提供商 获取操作所需的短期凭证。
沼泽之怒:你真幸运!泄露带有硬编码密钥的脚本在过去是一种常见做法,即使在可公开访问的 S3 存储桶上也是如此。你需要做的就是遍历存储桶中的对象并进行一些 grepping 来找到有趣的东西。
有时,由于配置缺陷(未被发现),用于部署的区域(本例中为 AWS S3 存储桶)对外部人员开放以供读取。 沼泽之怒 使用的是这样的:
aws s3 ls --recursive s3://<bucket_name>/<path>/ | \
awk '{print $4}' | \
xargs -I FNAME sh -c "echo FNAME; \
aws s3 cp s3://<bucket_name>/FNAME - | \
grep '<regex_pattern>'"
该存储桶可能是在配置模板中创建的,可以自动扫描以查找安全漏洞。
该工具的默认配置对我们来说只是一个玩具
为了举出具体的例子,我们来谈谈 詹金斯,最流行的 CI 工具之一。
沼泽之怒:你还记得 Jenkins 中的“启用安全性”复选框吗?有多少组织为了方便而选择不激活它?那些“任何人都可以做任何事”权限组合为默认?还有那些讨厌的 Jenkins 插件,比如 GitHub OAuth 插件配置人员选择了“向所有经过身份验证的用户授予读取权限”和“使用 GitHub 存储库权限”,从而允许我们访问他们的所有项目。
(抱歉,詹金斯,我拿你来举例😉
熟练掌握(甚至沉迷于)安全原则。其中之一是 默认安全 原则:控制应默认为最安全的设置。安全性应内置于 CI/CD 工具和 pipeline从一开始就考虑,而不是事后才考虑。但用户友好性和便利性往往与安全性相冲突。
对于 Jenkins 来说,内置身份验证太脆弱了: 永远不要使用 Jenkins 中的内置身份验证机制。最好选择第三方机制(SAML、LDAP、Google 等),使用基于角色的授权策略(“RBAC”)插件。并且要特别小心 admin 帐户。
照顾工作和 pipeline Jenkins 中的文件处理方式相同 配置即代码插件 及其配置文件,适用于 Jenkins 配置。
从自托管迁移 CI/CD 系统迁移到基于云的 SaaS 系统消除了一些允许组织网络内横向移动的潜在风险,但也增加了其他风险,例如必须在现有内部系统和外部化系统之间打开外部连接 CI/CD 工具。
组织应该努力cis应尽的注意加强 CI/CD 系统,从最严格的设置开始,逐渐开放所需的最低权限。 pipeline 步骤。
配置安全性 CI/CD 工具可能非常复杂。许多工具的插件或扩展都存在大多数漏洞,需要更新。
此类复杂工具或基准的安全错误配置扫描程序可能会有所帮助。
注入代码 pipeline 为了乐趣和利益的命令
M3M3N70:您是否曾经使用过不受信任的代码检出,其易受命令注入攻击的操作和脚本?
本节显示 pipeline 本身可能存在编码错误,使得不良行为者能够在 pipeline 不改变 pipeline 来源本身.例如使用 PR
第一个例子 不幸的 GitHub 工作流程:
# INSECURE. Provided as an example only.
on:
pull_request_target #1
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: $ #2
- uses: actions/setup-node@v1
- run: |
npm install #3
npm build
# ... more steps ...
技术与 pull_request_target 使用明确签出不受信任的 PR 来触发工作流触发器是一种危险的做法,可能会导致存储库受到损害。在示例中,不幸的组合如下:
pull_request_target事件,默认情况下,它对目标存储库和目标存储库机密具有写权限,甚至可以从外部分支写入,并在 PR 的目标存储库上下文中运行,- 从不受信任的仓库中签出 PR 代码,
- 触发任何可能对 PR 控制内容进行操作的脚本,例如
npm install和 - 不使用条件来触发
pull_request_target仅当为 PR 分配了某种“此 PR 已经过审查”标签时才会运行事件(外部用户不能为 PR 分配标签)。
第二个示例需要不受信任的输入(来自问题、评论或 pull request)作为传递给 pipeline 通过表达式命令。这是 pipeline 版本的操作系统命令注入漏洞。
- name: Check title
run: |
title="$"
if [[ ! $title =~ ^.*:\ .*$ ]]; then
echo "Bad issue title"
exit 1
fi
运行操作根据模板生成一个临时的 shell 脚本,其中 $ 被替换,使其容易受到 shell 命令注入攻击。使用虚假 GitHub 帐户的攻击者可以创建标题为 a"; bad_code_goes_here;#,轰!
沼泽之怒:哦,那些家伙只需打开一个问题就可以为命令注入打开大门……
GitHub 操作中存在代码执行漏洞,例如 gajira-评论,现已修复。请阅读 “GitHub 工作流程中不受信任的输入” 完整的细节。
这个故事的主旨: 在没有先审查 PR 的情况下,切勿从不受信任的来源签出并构建 PR。 这里的“不受信任”,除非经过严格的出处认证,否则可能意味着任何可能被劫持的开发者帐户。
此处意外部署了恶意软件!
持续部署 是自动化的高潮,但这一高潮可能会因缺乏适当的审批控制而受挫。 pipeline 流。
从源头全面自动化部署的风险 commit 对生产系统造成威胁的可能性包括恶意代码在未被发现的情况下部署到生产环境中的可能性,以及部署过程中出现错误导致中断或停机的可能性。
为了减轻这些风险,通常建议组织在部署过程中实施“硬中断”,这需要 人类的认可 在发布到最终环境之前。
他们正在关门
沼泽之怒:那些令人愉悦的默认密码 CI/CD 工具正在被清除。访问
/var/lib/jenkins/secrets/initialAdminPassword现在已经是死路一条了。现在许多工具都提供 2FA,这是 Covid 让其流行起来的,就连最懒惰的代码猴子也在使用它!M3M3N70:我们正在打击 2FA,但这并不容易。很难对这些人进行鱼叉式网络钓鱼,因为 “Scatter Swine” 与 Twilio 合作。使用 WebAuthn 密钥则困难得多。至少,我们可以尝试 窃取 cookies 来绕过 MFA,但需要闯入开发人员的盒子。
多因素身份验证是朝着限制身份验证机密泄露风险的正确方向迈出的良好一步。大多数现代 DevOps 工具都支持 MFA。WebAuthn/U2F 下的身份验证密钥(请参阅 FIDO2 项目) 如果管理得当,可能是 DevOps 中 MFA 的最佳选择。
沼泽之怒:DevOps 人员正在觉醒。他们血液中流淌着该死的“最小特权”思想。他们不再是代码猴子了。我们现在被审阅者当场抓住了。
事实上, pipeline现在比几年前更加强大了,删除了薄弱的操作和脚本,并增加了安全测试步骤,甚至可以检测到隐藏在隐蔽位置的植入者 commit和我们劫持的包裹。
读者的问题:从源代码构建软件并部署到生产中的过程是否是一项有风险的业务? 您是否认为您的 DevOps 处于 美好的时光 对于坏人?
最终建议
从哪里开始 CI/CD pipeline年代?
第一条建议很简单:小心 检讨 pipelines (他们是 危急 安全问题需要使用资源。审查成本高昂,但必须正确进行。审查人员应该知道要查看哪些内容。必须检查每个步骤是否存在缺陷。
也许配备自动恶意代码扫描器的专家审阅人员组合可能会有所帮助。
第二项建议是 培训编写代码的开发人员 pipeline并保持安全. 需要考虑的事项:
- 如何正确处理内部和云服务的身份验证,避免处理长期凭证的麻烦。
- 如何限制 pipelines 到它需要访问的确切资源集。最小特权原则再次闪耀光芒。
- 如何编写制作步骤 pipeline像版本固定一样可重现,并避免命令注入漏洞。
- 如何从安全角度批准部署(他们是其他人!):哪些安全 standard应该匹配,以及如何在 pipelines.
第三个建议是 配置 CI/CD 系统性。强身份验证、无默认密码或不安全设置、最小权限……注意安装的插件和扩展中的漏洞。这可能是后续帖子的重点,请继续关注。
第四项建议是 杠杆作用 CI/CD pipeline用于安全自动化. 源代码分析(SAST)、来源成分分析(SCA)、机密泄漏扫描、反恶意软件工具、容器安全扫描程序或自动运行时检测器(DAST 和恶意软件)可以在 pipeline. 你的组织可能会执行 standard关于安全扫描的报道 CI/CD.
提醒一下,这些工具并不能从等式中去除专家评审,否则您可能会产生虚假的安全感。
如果你熟悉 OWASP 前十名,那么最近一个不错的项目就是 OWASP顶级10 CI/CD 安全风险.
免责声明
(1)本文中的示例使用 GitHub 作为 SCM、AWS 作为云提供商,以及 GitHub Actions 或 Jenkins 作为 CI/CD 工具。它们并不比其他选择更弱/更安全。没有恶意!这些工具功能强大,需要适当使用。
(2) M3M3N70 以及 沼泽之怒 是虚构的人物。任何与人物或团体(无论是活着的还是死去的)的相似之处都纯属巧合……还是真的?
阅读更多
- Haymore,A.等人。 “10 个现实世界中我们如何妥协的故事 CI/CD pipelines. NCC Group,2022 年 XNUMX 月。
configure-aws-credentialsGitHub 操作 以及 在 Amazon Web Services 中配置 OpenID Connect 有关如何在 GitHub 工作流中运行 AWS 命令进行部署的详细信息。- 洛巴切夫斯基 J. “保障 GitHub Actions 和工作流程安全第 1 部分:防止 pwn 请求”. GitLab 安全实验室,2020 年 XNUMX 月。
- 洛巴切夫斯基 J. “确保 GitHub Actions 和工作流程安全第 2 部分:不受信任的输入”. GitLab 安全实验室,2021 年 XNUMX 月。
- OWASP。 “OWASP 前 10 CI/CD 安全风险””. 2022 年 XNUMX 月。
- Saltzer J. 和 Schroeder M. “计算机系统信息的保护”。1975 年 47 月。安全原则随着技术的发展而不断发展,但 XNUMX 年后,大多数 S&S 理念仍然有效。
- 英国 NCSC。 “确保构建和部署 pipeline=. 英国国家网络安全中心,2019 年 XNUMX 月。





