以为删了 Commit 密钥就安全?GitHub Actions 惊现大规模窃密攻击,排查与防御全指南
原创
Hankzheng
Hankzheng
技术修道场
2026年10月13日 08:00
广东
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
如果你这几天打开过 GitHub,或者你团队内部的 CI/CD 自动化流水线突然多出了一些名字看似“合规”的奇怪任务,请务必暂停手头的工作,先把这篇文章读完。
近期,多家安全团队披露了一场代号为 GhostAction 的大规模软件供应链投毒攻击。截至 2026 年 10 月 9 日,攻击者已攻陷超过 500 个高信誉度开发者账号,并在短短几天内向数万个开源及衍生仓库植入了恶意 GitHub Actions 工作流。
最具讽刺意味的伪装:黑客给这些恶意工作流起的名字极其正经——Security Audit(安全审计)或 GitHub Actions Security。它表面上挂着安全巡检的招牌,暗地里却在全速将你的云凭证、AI 模型接口 Key 和整个历史提交记录打包偷走。
今天,我就以一线工程师的视角,带大家复盘这场“攻击”的技术路径:黑客究竟是如何做到的?为什么你以为“早已删掉”的历史敏感凭据依旧逃不过扫描?面对这种供应链投毒,我们又该如何排查与彻底止血?
01. 攻击全貌:16 分钟批量感染 318 个仓库
受害者名单里包括了多位在开源界极具威望的资深作者:拥有 1.8 万 Star 的 Python 游戏引擎 pyxel 原作者 Takashi Kitao,以及 Uber 前开源项目 athenadriver 作者 Henry Wu(henrywoo)。
根据 StepSecurity 的监控时间线,整个入侵过程呈现出典型的工业化脚本作业特征:
- 13:20 UTC:
攻击者登录 Takashi Kitao 的账号,在 27 个代码仓库中强行推入恶意 workflow。
* 21:10–21:26 UTC:
仅隔 8 小时,攻击者切换至 Henry Wu 的凭据,在短短 16 分钟内向 318 个仓库完成了流水线投毒!
这并不是 GhostAction 的首次露面。该团伙早在 2025 年 9 月就曾掀起风浪,当时便收割了 817 个仓库中的 3325 个凭据(涵盖 PyPI、npm 与 DockerHub 的发布 Token)。而在此次 2026 年的攻势中,受害者甚至遭遇了复合攻击——例如在 8 月底,攻击者篡改了 kuafuai/DevOpsGPT 仓库,在其官方 Docker 镜像中直接嵌入了 XMRig 门罗币挖矿程序。
02. 攻击链路拆解:黑客的“四步偷法”
梳理完整的攻击链条,你会发现这套连招设计得极其紧凑:
⚡ 攻击执行闭环:
Step 1. 突破认证:通过泄露的开发机器日志或凭据转储,盗取核心维护者的 GitHub 个人访问令牌(PAT)。
Step 2. 侦察探测:调用 GitHub API 预先扫描目标仓库中已存在的 GitHub Actions Secrets 变量命名清单。
Step 3. 注入隐蔽文件:在主分支注入 security-audit.yml 或 github_actions_security.yml。
Step 4. 触发与回传:触发自动化 Runner 任务,搜刮整个上下文机密,通过 curl 经明文 HTTP 回传至受控节点 193.32.204[.]199。
值得注意的是,恶意工作流的触发配置被设为全天候监听:
- 支持
workflow_dispatch,方便攻击者在后台主动批量发包触发; - 配置了无过滤条件的 push 监听(匹配任何分支、任何 Tag)。这意味着不知情的维护者后续只要推代码,就会无意中帮黑客重新跑一次窃密程序。
03. 核心机制剖析:为什么连历史提交也难逃厄运?
很多研发同学常有一种侥幸心理:“我上周不小心把 API Key 传上去了,但我马上用新 Commit 给删掉了,现在主分支文件里干干净净,应该没事吧?”
大错特错!这正是本次 GhostAction 最狡猾的技术杀招。
1. 致命的克隆深度:fetch-depth: 0
通常在编写常规 CI 流水线时,官方的 actions/checkout 默认拉取的是单次 Commit(即浅克隆 depth: 1)。但黑客在此次恶意文件中显式写明了:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 致命点:拉取完整 Git 拓扑历史
fetch-depth: 0 会强制 Runner 本地完整还原整个仓库自创世以来的全部 Git 提交对象、分支以及 Tags!
2. 13 组高危特征正则的双层地毯式扫描
紧接着,恶意脚本内部定义了 13 类高价值敏感凭据的正则匹配模式,同时向两个维度开火:
- 工作区静态扫描:
扫除当前正在使用的源码、配置文件、环境变量模板。
* 提交树穿透扫描:
遍历全部 commit 变更差量。只要你历史上曾经手滑提交过密码,哪怕几秒后通过新的 Commit 覆写删除,只要 Git 历史指针未做重写压缩,都会被直接剥离还原!
🎯 本次被黑客定向收割的 13 种关键凭据类别:
• 云厂商 Key:AWS / Azure / GCP
• AI 基础设施:OpenAI / Anthropic / OpenRouter
• CI/CD 与 Registry:DockerHub / GHCR Token
• 包管理器凭据:npm / PyPI Token
• 网络与系统:SSH 私钥 / FTP / 数据库连接串
• 运维通信:Slack / Telegram / Discord Bot Token
3. 智能凭据拼装与静默外联
脚本不仅能捞凭据,还写了针对 AWS 凭据的关联算法:它会自动在扫描池中匹配 AKIA... 格式的 Access Key ID 与其对应的 Secret Access Key,拼装成一套可即刻调用的凭据组。
随后,所有数据被丢进 curl,向硬编码的黑客控制端 193.32.204[.]199 发送 HTTP 明文 POST 请求。更恶毒的是,即便某仓库干干净净、没有被扫出任何密钥,每次运行也会回传此仓库的全局唯一标识。攻击者借此直接绘制出了一张可执行供应链跳板的网络拓扑全景图。
04. 级联放大:Fork 与私有仓库的“降维打击”
你可能会问:“中招的只是开源公共项目,我们团队的核心业务代码都在私有仓库,这跟我们有关系吗?”
恰恰相反,私有仓库反而是此次暴露风险最高的地带!
以 Henry Wu 的账号为例,其受害命名空间下共挂载了 279 个下游 Fork 仓库:
- 下游继承扩散:
下游开发者若 Fork 了受感染的母仓库,或者同步了上游的主干分支,恶意工作流文件便会无缝进驻下游;
* 私有环境更无防备:
许多团队习惯把核心业务存放在私有仓库中,并在日常开发中随意将生产数据库密码、第三方 API Token 明文写在代码或私有配置里。一旦私有分支继承了这个恶意 Action 并在 GitHub 官方云端 Runner 启动执行,藏在私有库里的内部密钥将被全盘收割。
05. 应急排查与自救指南:4 步实操止血手册
建议各位研发主管、架构师以及运维老铁们,立刻按照以下步骤排查个人与企业 Organization 旗下的全部代码资产:
Step 1. 全局搜索恶意工作流文件
在所有仓库(涵盖所有分支与 Forks)中排查是否存在以下两个文件:
• .github/workflows/security-audit.yml
• .github/workflows/github\_actions\_security.yml
⚠️ 预警判定:凡是在 2026 年 8 月 31 日以后新增过上述文件的仓库,请直接按“资产已完全沦陷”定性处理!
Step 2. 彻底作废既有凭证并阻断回传
- 立即吊销受影响账号现存的所有 Personal Access Tokens (PAT)、部署密钥和已授权的 OAuth App;
- 强制所有管理员和项目维护者重置密码,并开启基于 FIDO2 / WebAuthn 的硬件密钥或 2FA;
- 从所有分支及标签中物理删除上述两个恶意
.yml配置文件。
Step 3. 核心凭据强制轮转
这一步极其繁琐,但必须硬着头皮执行。请立即执行凭据轮转:
- 云厂商:进入 AWS、Azure、阿里云、腾讯云等控制台,废除全部涉密 AccessKey 并重置;
- AI 生态:立即重新生成 OpenAI、Anthropic、OpenRouter 等平台的 API Key;
- 发布渠道:撤销并更新 npm、PyPI、DockerHub、GHCR 访问 Token;
- 基建运维:更换关联服务器的 SSH Key,审查
~/.ssh/authorized_keys,并修改生产数据库连接密码。
Step 4. 彻底物理净化 Git 历史
普通 git rm 根本无法抹去历史对象。必须通过专业工具重写提交历史:
# 使用官方推荐的高效重写工具 git-filter-repo
pip install git-filter-repo
# 定义需要替换剔除的敏感文本映射后执行重写
git filter-repo --replace-text expressions.txt
# 强制推送更新所有远程分支与 Tags
git push origin --force --all
git push origin --force --tags
注:重写历史属于破坏性操作,建议在操作前做好整库离线镜像备份。
06. 架构反思:现代 CI/CD 应该如何构建纵深防御?
GhostAction 事件向所有技术团队释放了一个极其清晰的信号:软件供应链的攻击阵地,已经从单纯的“第三方代码包投毒”,演变为“对自动化编排特权的高级狩猎”。
在工程实践中,我们必须落实以下四项防线配置:
1. 坚决践行 GitHub Actions 最小权限原则
在编写任意 Workflow 时,强制在顶层明确收窄 permissions 权限,绝不给默认的 GITHUB_TOKEN 分配宽泛的写权限:
permissions:
contents: read # 强制显式声明只读,收紧写权限
2. 全面以 OIDC 替代长期静态密钥
坚决弃用存储在 Actions Secrets 里的静态、长期有效的 AWS / 云平台 AccessKey。全面迁移至基于 OpenID Connect (OIDC) 的短期 Token 角色扮演方案。即使 Actions 环境遭受越权,黑客拿到的临时凭证也会在几分钟内自动作废。
3. 强化 Runner 出网规则控制
对于自建 Runner,必须在网络边界启用出站白名单策略。像本次攻击中直接通过 HTTP 协议向外部裸 IP(193.32.204[.]199)回传数据的网络行为,在严格的出网策略下应当被第一时间阻断并告警。
4. 限制 Fork 运行 Actions 的默认策略
在 GitHub 组织与仓库的 Settings -> Actions -> General 中,将 Fork 仓库提交的 PR 运行策略设置为“需要团队协作者审批后方可运行”,切断跨仓库级联传播。
写在最后:
软件供应链攻防的核心,始终是对“信任链条”的争夺。黑客正是利用了广大开发者对知名开源项目的惯性信任、对“安全审计”字样的放松防备,才制造了这场席卷数万仓库的投毒惨案。
安全从来没有绝对的事后诸葛亮。赶紧把这篇文章转发给身边的研发、SRE 和安全老铁,一起登录控制台彻查一波吧!
💬 互动交流:你在日常排查中遇到过类似的 CI/CD 异常吗?针对历史 Commit 抹除敏感信息有什么踩坑经历?欢迎在下方评论区交流探讨!
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论