投毒ClaudeCode:一条GitHubIssue如何击穿供应链

admin 2026-06-11 04:41:07 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档分析了ClaudeCodeGitHubActions的供应链安全漏洞,攻击者可通过恶意GitHubApp绕过权限检查,注入恶意输入导致仓库沦陷。关键发现包括默认配置允许GitHubApp触发工作流、Agent模式缺乏执行者类型检查、以及错误配置允许外部用户触发。Anthropic已在v1.0.94修复漏洞,建议用户审计工作流配置并审查运行日志。 综合评分: 87 文章分类: 漏洞分析,供应链安全,解决方案,安全工具,WEB安全


cover_image

投毒 Claude Code:一条 GitHub Issue 如何击穿供应链

原创

骨哥说事 骨哥说事

骨哥说事

2026年6月5日 10:37 上海

在小说阅读器读本章

去阅读

| | | — | | 声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。 |

#

#

防走失:https://gugesay.com/

不想错过任何消息?设置星标↓ ↓ ↓

#

引言

大家好,我是RyotaK(@ryotkak),GMO Flatt Security 公司的一名安全研究员。

在我发表了上一篇文章(以 8 种不同方式攻击Claude Code)之后,我继续调查了 Claude 相关产品,又发现了几处漏洞。

在本文中,我将解释 Claude Code 的 GitHub Actions 中的一个漏洞,该漏洞可能允许攻击者攻陷任何使用 Claude Code 工作流的代码仓库,包括 Anthropic 自己的仓库

注意: 本文描述的错误配置问题的一些变体在本文发布前就已在野外被积极利用。虽然问题现已得到缓解,但如果你正在使用 Claude Code GitHub Actions,我强烈建议:

  • 审计你的配置,检查是否存在本文描述的易受攻击的模式。
  • 审查工作流运行日志,查找任何被入侵的迹象。

摘要

Anthropic 提供了一个 GitHub Actions 工作流,将 Claude Code 集成到 CI/CD 流水线中。

我发现了一个漏洞,允许攻击者绕过其权限控制,将不受信任的输入注入到一个设计为只处理受信任输入的工作流中。默认情况下,该工作流对代码、Issue、PR、讨论和工作流文件具有读写权限,因此此绕过可用于向仓库注入恶意代码或窃取敏感信息。

由于 Claude Code GitHub Actions 仓库本身也使用了这个工作流,攻击者甚至可以入侵该 Action 的源代码,从而传播到每个下游仓库,包括 Anthropic 自己的仓库。

另外,我还发现 Anthropic 提供的示例工作流中存在一个错误配置,允许任何外部贡献者泄露 GitHub Token 并攻陷仓库

Anthropic 已确认这些漏洞,并在 Claude Code GitHub Actions v1.0.94 及之后版本中修复了它们。

Claude Code GitHub Actions 概览

Claude Code GitHub Actions 是由 Anthropic 提供的、用于将 Claude Code 集成到 CI/CD 流水线中的工作流。它可以用于自动化代码审查、分类和标记 Issue、以及基于评论生成代码。

该工作流有两种模式:

  • tag 模式: 当用户在 Issue 或 PR 评论中提及特定关键词(默认为 @claude)时触发。
  • agent 模式: 当工作流配置了 prompt 输入时触发。此模式通常用于运行斜杠命令或预定义任务。

例如,以下配置在 Agent 模式下运行 /dedupe slash 命令:

 - name: Run Claude Code slash command        uses: anthropics/claude-code-action@v1        [...]        with:          [...]          prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"

为了执行 GitHub 相关操作,该工作流需要在你的仓库上安装 Claude GitHub App。该 App 具有以下默认权限:

  • 对仓库内容的读写权限(代码)
  • 对 Issue 和 PR 的读写权限
  • 对讨论的读写权限
  • 对工作流的读写权限

默认这些权限很强大,但也带来了安全风险。如果工作流处理不受信任的输入,攻击者可以通过间接提示注入来操纵 Claude Code,并滥用这些权限

Claude Code GitHub Actions 的权限模型

为了缓解这一风险,Claude Code GitHub Actions 默认禁止没有写入权限(write access)的用户触发该工作流。此权限控制通过 checkWritePermissions 函数实现,该函数会检查执行者是否对仓库拥有 write 或 admin 权限。

Repository Access: The action can only be triggered by users with write access to the repository

该权限控制通过 checkWritePermissions 函数实现:

src/github/validation/permissions.ts 第 13-68 行:


export&nbsp;async&nbsp;function&nbsp;checkWritePermissions(&nbsp; [...]):&nbsp;Promise<boolean> {&nbsp; [...]&nbsp; &nbsp; core.info(`Checking permissions for actor:&nbsp;${actor}`);&nbsp; &nbsp; [...]&nbsp; &nbsp;&nbsp;// Check if the actor is a GitHub App (bot user)&nbsp; &nbsp;&nbsp;if&nbsp;(actor.endsWith("[bot]")) {&nbsp; &nbsp; &nbsp; core.info(`Actor is a GitHub App:&nbsp;${actor}`);&nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;true;&nbsp; &nbsp; }&nbsp; &nbsp; [...]&nbsp; &nbsp;&nbsp;if&nbsp;(permissionLevel ===&nbsp;"admin"&nbsp;|| permissionLevel ===&nbsp;"write") {&nbsp; &nbsp; &nbsp; core.info(`Actor has write access:&nbsp;${permissionLevel}`);&nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;true;&nbsp; &nbsp; }&nbsp;else&nbsp;{&nbsp; &nbsp; &nbsp; core.warning(`Actor has insufficient permissions:&nbsp;${permissionLevel}`);&nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;false;&nbsp; &nbsp; }

关键点: 该函数会无条件允许任何 GitHub App 通过,无论其实际权限如何。乍一看这似乎合理,因为 GitHub Apps 通常是由仓库管理员安装的受信任实体。然而,这一假设在实践中是有问题的。

GitHub Apps 与公共仓库

根据 GitHub 官方文档,GitHub Apps 在代表用户操作时,对公共资源拥有隐式的读取权限。这种隐式权限不仅限于读取。就像任何 GitHub 用户都可以在他们不拥有的仓库上打开 Issue 一样,GitHub App 可以使用其安装凭证在任何公共仓库上创建 Issue 和 PR,即使该 App 并未安装在该目标仓库上。

这意味着可以利用以下步骤绕过 checkWritePermissions 的检查:

  1. 创建并安装恶意 App: 攻击者创建一个 GitHub App(称为 malicious-app),并将其安装在自己的仓库上(无需特殊权限)。
  2. 触发目标工作流: 使用 malicious-app 的安装凭证,在目标公共仓库中创建一个 Issue 或 PR,以此触发 Claude Code GitHub Actions 工作流。
  3. 绕过权限检查: 由于执行者是 GitHub App,checkWritePermissions 返回 true,工作流继续处理攻击者控制的内容。

tag 模式还有一个额外的检查(checkHumanActor)来验证执行者是否为 User 类型。然而,在发现时,agent 模式缺乏此检查,留下了被绕过的可能。

数据泄露与仓库沦陷

通过这种绕过方式,攻击者可以触发工作流并注入不受信任的输入,欺骗 Claude Code 执行非预期的操作。

.github/workflows/claude-issue-triage.yml 第 44-103 行:

&nbsp; &nbsp; - name: Run Claude Code for Issue Triage&nbsp; &nbsp; &nbsp; &nbsp; timeout-minutes:&nbsp;5&nbsp; &nbsp; &nbsp; &nbsp; uses: anthropics/claude-code-action@v1&nbsp; &nbsp; &nbsp; &nbsp; env:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GH_TOKEN: ${{ secrets.GITHUB_TOKEN&nbsp;}}&nbsp; &nbsp; &nbsp; &nbsp; with:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prompt: |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [...]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Issue Information:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - REPO: ${{ github.repository&nbsp;}}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - ISSUE_NUMBER: ${{ github.event.issue.number&nbsp;}}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[...]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Start by using mcp__github__get_issue&nbsp;to&nbsp;get the issue&nbsp;details&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;[...]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; claude_args: |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [...]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --allowedTools&nbsp;"Bash(gh label list),mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues"

例如,在 anthropics/claude-code 仓库中使用的 Claude Issue Triage 工作流会将 Claude Code 配置成允许使用 mcp__github__update_issue 工具来回写数据到 Issue。

通过精心构造一个带有伪造错误信息的 Issue 描述,攻击者可以欺骗 Claude Code 执行 Bash 命令(如 cat /proc/self/environ读取环境变量。环境变量中包含了该工作流进程的所有秘密,包括关键的 OIDC Token 凭据

获取到的 OIDC Token 凭据可以被攻击者用于请求 Claude GitHub App 的安装凭证(installation token),该凭证拥有对目标仓库内容的完全写权限。这意味着攻击者可以直接向仓库推送恶意代码

这个 agent 模式的工作流也存在于 anthropics/claude-code-action 仓库本身。这意味着攻击者可以使用相同的技术入侵该 Action 自身的源代码,进而注入恶意代码,并传播到所有依赖它的仓库。

完整的攻击场景是:

  1. 攻击者创建一个恶意 GitHub App 并将其安装在自己的仓库。
  2. 使用该 App 的安装凭证,在 anthropics/claude-code-action 仓库创建一个包含提示注入负载的 Issue 或 PR。
  3. Claude Code 处理该 Issue,并被诱骗读取 /proc/self/environ
  4. 包含 OIDC Token 凭据的环境变量通过 Issue 被泄露出去。
  5. 攻击者用 OIDC Token 凭据交换到 Claude GitHub App 的安装凭证。
  6. 攻击者使用该安装凭证向 anthropics/claude-code-action 仓库推送恶意代码。
  7. 使用 Claude Code GitHub Actions 的每一个仓库都被攻陷。

为修复此问题,Anthropic 添加了一个检查,默认禁止 GitHub Apps 触发工作流

diff --git a/src/modes/agent/index.ts b/src/modes/agent/index.tsindex 1b992a799..59b78b405 100644--- a/src/modes/agent/index.ts+++ b/src/modes/agent/index.ts@@ -80,7 +81,14 @@&nbsp;export const agentMode: Mode = {&nbsp; &nbsp; &nbsp;return false;&nbsp; &nbsp;},
- &nbsp;async prepare({ context, githubToken }: ModeOptions): Promise<ModeResult> {+ &nbsp;async prepare({+ &nbsp; &nbsp;context,+ &nbsp; &nbsp;octokit,+ &nbsp; &nbsp;githubToken,+ &nbsp;}: ModeOptions): Promise<ModeResult> {+ &nbsp; &nbsp;// Check if actor is human (prevents bot-triggered loops)+ &nbsp; &nbsp;await checkHumanActor(octokit.rest, context);+&nbsp; &nbsp; &nbsp;// Configure git authentication for agent mode (same as tag mode)&nbsp; &nbsp; &nbsp;// SSH signing takes precedence if provided&nbsp; &nbsp; &nbsp;const useSshSigning = !!context.inputs.sshSigningKey;

Claude Code GitHub Actions 的常见错误配置

在调查过程中,我注意到 Anthropic 自己仓库中存在一个常见的错误配置,即使不需要 GitHub App 绕过,也可能导致类似的严重程度。

例如,前面提到的 Claude Issue Triage 工作流包含配置 allowed_non_write_users: "*",这个设置允许任何用户触发该工作流。官方安全文档将此标记为高风险选项。

.github/workflows/claude-issue-triage.yml 第 11-51 行:

&nbsp;permissions:&nbsp; &nbsp; &nbsp; [...]&nbsp; &nbsp; &nbsp; issues: write&nbsp; &nbsp; &nbsp; [...]&nbsp; &nbsp; &nbsp; - name: Run Claude Code&nbsp;for&nbsp;Issue Triage&nbsp; &nbsp; &nbsp; &nbsp; timeout-minutes: 5&nbsp; &nbsp; &nbsp; &nbsp; uses: anthropics/claude-code-action@v1&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;env:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GH_TOKEN:&nbsp;${{ secrets.GITHUB_TOKEN }}&nbsp; &nbsp; &nbsp; &nbsp; with:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; github_token:&nbsp;${{ secrets.GITHUB_TOKEN }}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; allowed_non_write_users:&nbsp;"*"

即使按照文档建议,仅用于拥有“极其有限权限”(例如只有 issues: write 权限)的工作流,也存在几个问题:

  1. issues: write 权限并不真的很有限。它仍然允许攻击者删除或编辑现有的 Issue。
  2. 工作流需要 Anthropic API Key,这本身就是敏感信息。将其暴露给不受信任的输入已使其不适合该用途。
  3. 即使权限有限,数据泄露仍然可能发生:Claude Code GitHub Actions 默认会向工作流运行的摘要部分发布已完成任务的摘要,而这些摘要是公开可见的,可以被用来泄露信息。

链式利用工作流实现完全沦陷

issues: write 权限还允许攻击者编辑由具有写入权限的用户发布的 Issue。通过在受信任用户创建 Issue 之后、但在 Claude Code 读取它之前修改该 Issue,攻击者可以注入恶意指令。然后,Claude 会将这些指令作为受信任的上下文处理,因为该 Issue最初是由通过 checkWritePermissions 检查的用户创建的

当攻击者能够通过一个工作流(如 Issue 分类工作流)获得 issues: write 权限后,他可以通过链式利用一个由受信任用户基于 @claude 提及触发的默认 tag 模式工作流(该工作流拥有 id-token: write 权限)来获取 OIDC Token 凭据,进而获取安装凭证,最终获得对仓库的完全控制。

由于此错误配置存在于官方的示例工作流中,许多使用 Claude Code GitHub Actions 的仓库都继承了同样的漏洞。

示例/issue-triage.yml:

name: Claude Codeon:&nbsp; issue_comment:&nbsp; &nbsp; types: [created]&nbsp; pull_request_review_comment:&nbsp; &nbsp; types: [created]&nbsp; issues:&nbsp; &nbsp; types: [opened, assigned]&nbsp; pull_request_review:&nbsp; &nbsp; types: [submitted]jobs:&nbsp; claude:&nbsp; &nbsp;&nbsp;if: |&nbsp; &nbsp; &nbsp; (github.event_name ==&nbsp;'issue_comment'&nbsp;&& contains(github.event.comment.body,&nbsp;'@claude')) ||&nbsp; &nbsp; &nbsp; (github.event_name ==&nbsp;'pull_request_review_comment'&nbsp;&& contains(github.event.comment.body,&nbsp;'@claude')) ||&nbsp; &nbsp; &nbsp; (github.event_name ==&nbsp;'pull_request_review'&nbsp;&& contains(github.event.review.body,&nbsp;'@claude')) ||&nbsp; &nbsp; &nbsp; (github.event_name ==&nbsp;'issues'&nbsp;&& (contains(github.event.issue.body,&nbsp;'@claude') || contains(github.event.issue.title,&nbsp;'@claude'))) &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; runs-on: ubuntu-latest&nbsp; &nbsp; permissions:&nbsp; &nbsp; &nbsp; contents:&nbsp;read&nbsp; &nbsp; &nbsp; pull-requests:&nbsp;read&nbsp; &nbsp; &nbsp; issues:&nbsp;read&nbsp; &nbsp; &nbsp; id-token: write&nbsp; &nbsp; &nbsp; actions:&nbsp;read&nbsp;# Required for Claude to read CI results on PRs&nbsp; &nbsp; steps:&nbsp; &nbsp; &nbsp; [...]&nbsp; &nbsp; &nbsp; - name: Run Claude Code&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;id: claude&nbsp; &nbsp; &nbsp; &nbsp; uses: anthropics/claude-code-action@v1

在我向 Anthropic 报告此错误配置后,他们默认禁用了工作流运行摘要部分,切断了这条特定的泄露渠道,即使进行了此修复,如果工作流授予了可能允许数据泄露的命令执行权限,秘密仍然可能泄露。

因此,我强烈建议你审计工作流中是否有使用 allowed_non_write_users,并检查权限和机密(secrets)是否相应受限。 如果你的工作流拥有可能实现数据泄露的权限,应将其限制给特定的受信任用户或移除这些权限。

总结

在本文中,解释了一种可导致攻击者攻陷包括 Anthropic 自身仓库在内的、所有使用 Claude Code GitHub Actions 仓库的供应链漏洞

Anthropic 对此响应迅速,修补了问题。他们移除了 GitHub Apps 的默认绕过,禁用了摘要部分,修复了其他数据泄露途径,并决定擦除 Claude Code 产生的子进程中暴露的环境变量,以缓解我报告的其他泄露途径。

尽管如此,供应链安全仍然是一个对研究者激励相对不足的领域。随着 AI 驱动的工具和服务的兴起,值得记住的是:提示注入仍然是一个未解决的问题,并且仍然可以被用来控制 AI 系统的行为。

时间线

| 日期 | 事件 | | — | — | | 2026-01-12 | 权限绕过漏洞报告给 Anthropic | | 2026-01-16 | Anthropic [修复了权限绕过漏洞](https://github.com/anthropics/claude-code-action/commit/1bbc9e7ff7d48e1299f7fa9698273d248e0cafea | | 2026-01-17 | 向Anthropic报告的配置错误问题 | | 2026-02-17 | Cline的GitHub操作中类似的错误配置在野外被利用 | | 2026-2月-4月 | 几轮补救和后续绕过 | | 2026-6-1 | 发表本文章 |

原文:https://flatt.tech/research/posts/poisoning-claude-code-one-github-issue-to-break-the-supply-chain/

  • END –

感谢阅读,如果觉得还不错的话,动动手指给个三连吧~


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:骨哥说事 骨哥说事 骨哥说事《投毒 Claude Code:一条 GitHub Issue 如何击穿供应链》

一个典型的sqli 网络安全文章

一个典型的sqli

文章总结: 本文分析一个典型SQL注入漏洞案例,展示针对腾讯视频票务API接口的两种盲注技术:布尔盲注通过构造逻辑表达式改变WHERE/HAVING子句判断,时
评论:0   参与:  0