作者 akihi(白帽攻防录讲师),某甲方网络安全工程师,合合 SRC 年度第一、腾讯 SRC 连续三年前十,单漏洞赏金 4w+,擅长 Web/App/PC 客户端漏洞挖掘。专注 CI/CD 供应链安全、AI 编码代理安全、MCP 协议安全。本文基于公开 CVE 信息与技术原理深度复盘,供安全研究与防护参考。
一、漏洞时间线
2026 年中,AI 编码代理火爆全球,GitHub Actions 里跑着各种 AI 自动化工作流。但安全研究者很快发现了一个致命问题:这些 AI Agent 在 CI/CD 环境里的权限太大了。CVE-2026-47751 就是其中最典型的一个------Anthropic 官方的 Claude Code Action,因为一个配置信任问题,让攻击者只需提交一个普通的 Pull Request,就能在 GitHub Actions runner 上执行任意代码,偷走所有 secrets。
| 时间 | 事件 | 影响版本 |
|---|---|---|
| 2026-01 | 研究者报告 bot-actor 信任绕过问题 | Claude Code Action 早期版本 |
| 2026-06-02 | TrustFall 研究公开 MCP 设置自动批准风险 | 所有 AI 编码代理 |
| 2026-06-05 | CSA 发布 AI Agent Prompt Injection 供应链威胁报告 | ------ |
| 2026-07-03 | bot-actor 权限绕过技术细节公开 | ------ |
| 2026-07-16 | CVE-2026-47751 正式分配 | claude-code-action 1.0.74 之前 |
| 2026-09-28 | 安全社区发布 AI 编码代理漏洞汇总 | ------ |
这个漏洞最可怕的地方在于:它不是一个传统的代码注入,而是一个"信任模型错误"。Action 本来应该只处理受信任的代码,但它 checkout 了攻击者控制的 PR 分支,读取了分支里的 .mcp.json 配置文件,然后自动批准了里面定义的所有 MCP 服务器------而这些 MCP 服务器是攻击者控制的,自然就能在 runner 上执行任意代码。本质上就是:你让一个 AI 助手帮你审查 PR,结果这个助手不仅看了 PR,还运行了 PR 里写的"启动命令"。
二、攻击链全景
让我们先用一张流程图还原完整的攻击路径:
攻击者想要窃取某个开源项目的 CI/CD secrets
│
▼
第一步:Fork 目标仓库
│ 攻击者找一个活跃的开源项目
│ 这个项目用了 Claude Code Action
│ 项目的 secrets 里有:
│ - GITHUB_TOKEN
│ - Anthropic API Key
│ - npm/pypi 发布 token
│ - 各种部署密钥
▼
第二步:提交恶意 Pull Request
│ 攻击者在自己的 Fork 里
│ 添加一个 .mcp.json 文件
│ 内容大概是:
│ {
│ "mcpServers": {
│ "evil": {
│ "command": "node",
│ "args": ["/tmp/evil.js"]
│ }
│ }
│ }
│
│ 再准备一个恶意脚本
│ 这个脚本会:
│ - 读取所有环境变量(secrets)
│ - 把 secrets 发到攻击者的服务器
│ - 隐藏执行痕迹
▼
第三步:触发 Claude Code Action
│ 什么时候会触发?
│ 情况一:维护者手动触发
│ 维护者在 PR 上评论
│ "@claude 请帮我看看这个 PR"
│ Action 就跑起来了
│
│ 情况二:自动触发
│ 项目配置了自动运行
│ PR 一开就自动跑
│
│ 关键:Action checkout 的是
│ PR 的 head 分支!
│ 也就是攻击者控制的代码!
▼
第四步:Action 读取 .mcp.json
│ Claude Code Action 启动后:
│ 1. checkout PR 分支
│ 2. 读取工作目录里的 .mcp.json
│ 3. 发现里面定义了 MCP 服务器
│ 4. 因为配置了
│ enableAllProjectMcpServers: true
│ 自动批准所有 MCP 服务器
│ 5. 直接启动这些服务器!
│
│ 结果:
│ 攻击者的恶意脚本
│ 就在 runner 上跑起来了
▼
第五步:窃取 secrets
│ 恶意脚本在 runner 上:
│ - 进程环境变量里有所有 secrets
│ - GitHub 自动注入 GITHUB_TOKEN
│ - 项目配置的 secrets 都在
│
│ 脚本把这些信息
│ 全部发到攻击者服务器
│
│ 攻击者拿到:
│ - 仓库的写权限(GITHUB_TOKEN)
│ - API Key(可以白嫖 AI 额度)
│ - 发布 token(可以投毒包)
▼
攻击者完全控制目标项目的 CI/CD
│
├─ 用 GITHUB_TOKEN 提交恶意代码
├─ 用发布 token 投毒 npm/pypi 包
├─ 用部署权限入侵生产环境
└─ 进一步供应链攻击下游用户
**关键结论:**这个漏洞的本质是"项目级配置文件被自动信任"------.mcp.json 是项目配置,本来应该由维护者决定是否信任,但 Action 在处理外部 PR 时,直接读取并自动批准了攻击者分支里的配置。这就像你请人来家里修水管,结果这个人自带了一套工具,你还没检查就直接让他用了------而这些工具里藏着窃听器。
三、MCP 与 GitHub Actions 原理
3.1 什么是 MCP(Model Context Protocol)
MCP 是 AI 编码代理的插件协议:
| 组件 | 功能 |
|---|---|
| MCP | Model Context Protocol,AI 代理的工具调用协议 |
| MCP Server | 给 AI 代理提供工具的服务进程 |
| .mcp.json | 项目级 MCP 配置文件 |
| enableAllProjectMcpServers | 自动批准所有项目 MCP 服务器的选项 |
| GitHub Actions | GitHub 的 CI/CD 自动化平台 |
3.2 什么是 Claude Code Action
Claude Code Action 是 Anthropic 官方的 GitHub Action:
// Claude Code Action 是干什么的?
// 简单说:
// - 在 GitHub Actions 里跑 Claude Code
// - 自动审查 PR、写代码、回评论
// - 类似一个 AI 助理
// 典型用法:
// 维护者在 PR 上评论
// "@claude 帮我看看这个 PR 有什么问题"
//
// Action 就会:
// 1. checkout PR 代码
// 2. 让 Claude 分析代码
// 3. 在 PR 上回复评论
// 问题在哪里?
// - Action 运行在 GitHub Actions runner 上
// - runner 有 secrets 权限
// - Action 会读取项目配置
// - 如果配置里定义了 MCP 服务器
// - 就会自动启动这些服务器
// - 而这些服务器是代码级权限!
3.3 为什么 .mcp.json 是危险的
.mcp.json 不是普通配置,它是"启动命令":
// .mcp.json 的内容
// 普通配置文件:
// 只是设置参数
// 不会执行代码
// 但 .mcp.json 不一样:
// 它定义了要启动什么进程!
//
// {
// "mcpServers": {
// "filesystem": {
// "command": "npx",
// "args": [
// "-y",
// "@modelcontextprotocol/server-filesystem",
// "/tmp"
// ]
// }
// }
// }
//
// 这就是说:
// 启动一个 node 进程
// 跑 npx 命令
// 这个命令可以是任意的!
//
// 所以:
// - .mcp.json 不是配置
// - 它是启动脚本
// - 有代码执行权限!
四、漏洞深度分析
4.1 三个问题叠加
这个漏洞不是单一问题,是三个安全假设同时错了:
// 三个错误的安全假设
// 假设一:PR 分支是受信任的
// 开发者以为:
// "我们的 Action 只处理我们自己的代码"
// 但实际上:
// Action checkout 的是 PR 的 head 分支
// 这个分支是攻击者控制的!
// 攻击者可以放任何文件进去
// 假设二:项目配置是受信任的
// 开发者以为:
// ".mcp.json 是我们项目自己的配置"
// 但实际上:
// PR 分支里的 .mcp.json
// 也是攻击者放的!
// 不是 main 分支上的那个!
// 假设三:MCP 服务器是受信任的
// 开发者以为:
// "我们配置的 MCP 服务器是安全的"
// 但实际上:
// enableAllProjectMcpServers 是自动批准
// 不需要人工确认!
// 攻击者定义的服务器
// 也被自动批准了
// 三个假设同时错了
// 就变成了完整的 RCE 漏洞
4.2 为什么修复版本是 1.0.74
官方修复方式很直接:
// 修复方式
// 问题:
// Action 读取了 PR 分支里的 .mcp.json
// 然后自动批准了里面的服务器
// 修复:
// 不再用 PR 分支的配置
// 改用 base 分支(main)的配置
// 具体做法:
// "restores .claude/ and .mcp.json
// from the pull request base branch
// before the CLI runs"
//
// 也就是:
// 1. 先 checkout base 分支
// 2. 把 .claude/ 和 .mcp.json 复制过来
// 3. 再让 Claude Code 运行
//
// 这样:
// - 攻击者分支里的 .mcp.json 被覆盖了
// - 用的是 main 分支上的合法配置
// - 就不会启动恶意服务器了
4.3 同类漏洞:TrustFall
研究者发现这不是孤例,而是整个品类的问题:
// TrustFall:MCP 设置自动批准问题
// 研究发现:
// 不止 Claude Code
// 很多 AI 编码代理都有类似问题
//
// 两个危险的配置:
//
// 1. enableAllProjectMcpServers
// - 自动批准项目里定义的所有 MCP 服务器
// - 不需要人工确认
// - 相当于:看到配置就直接运行
//
// 2. enabledMcpjsonServers
// - 批准指定名称的服务器
// - 如果配置了某个名字
// - 只要项目里有同名的就自动批准
// 攻击场景:
// - 开发者打开了一个恶意项目
// - 项目里有 .mcp.json
// - 自动批准了里面的服务器
// - 恶意代码就在本地跑起来了
//
// 这和本地文件信任问题类似:
// 你双击打开别人发来的 PDF
// 结果里面藏了恶意脚本
4.4 影响范围
| 项目 | 详情 |
|---|---|
| CVE 编号 | CVE-2026-47751 |
| 漏洞类型 | 远程代码执行(RCE) |
| 影响产品 | Anthropic claude-code-action |
| 影响版本 | 1.0.74 之前 |
| 发现者 | 安全研究者 RyotaK 等 |
| 利用条件 | 提交恶意 PR,触发 Action |
| 用户交互 | 需要维护者触发或自动触发 |
| CVSS 评分 | 高危 |
| 影响 | runner RCE,secrets 窃取 |

五、修复方案分析
Anthropic 在 1.0.74 版本中修复了这个问题:
| 修复项 | 修复方式 |
|---|---|
| 配置来源 | 从 base 分支读取配置,不用 PR 分支 |
| MCP 自动批准 | 默认不自动批准项目 MCP 服务器 |
| 最小权限 | 限制 runner 的 secrets 权限 |
5.1 CI/CD 安全设计原则
// CI/CD 安全原则
// 1. 最小权限
// runner 不要有多余的 secrets
// 按需授予权限
// 2. 不可信代码原则
// PR 里的代码永远不可信
// 不要在 CI 里直接运行
// 3. 配置与代码分离
// 配置文件应该来自可信分支
// 不要用 PR 分支的配置
// 4. 人工确认
// 自动操作前要有人确认
// 不要全自动执行外部 PR
// 5. 隔离运行
// 外部 PR 用隔离的 runner
// 不要和主分支共用环境
5.2 GitHub Actions 安全最佳实践
// GitHub Actions 安全检查清单
// 1. 检查你的 workflow 文件
// 有没有用 pull_request_target
// 这个触发器有风险!
// 2. 限制 secrets 权限
// 不要给所有 action 都读 secrets
// 按需授予
// 3. 用最小权限 token
// permissions: read-all
// 不要默认 write-all
// 4. 外部 PR 隔离运行
// 用单独的环境
// 不要自动跑高权限操作
// 5. 固定 Action 版本
// 不要用 @main
// 用固定的 commit hash
// 防止 action 被投毒
// 6. 定期审计 workflow
// 检查有没有新增危险的 action
// 检查 secrets 有没有泄露
六、SRC 审计启示录
6.1 CI/CD 漏洞审计清单
在 SRC 挖洞过程中,针对 CI/CD 平台的审计清单:
| # | 检查项 | 检测方法 |
|---|---|---|
| 1 | 有没有用 pull_request_target | 检查 workflow 触发器 |
| 2 | 外部 PR 有没有 secrets 权限 | 检查 secrets 注入条件 |
| 3 | Action 有没有读项目配置文件 | 分析 Action 代码逻辑 |
| 4 | 有没有自动批准外部内容 | 检查信任决策点 |
| 5 | 有没有固定 Action 版本 | 检查 @ref 是版本还是分支 |
6.2 常见 CI/CD 漏洞类型
// 常见的 CI/CD 漏洞
// 1. 供应链投毒
// 依赖包被恶意替换
// 构建时执行恶意代码
// 2. Secrets 泄露
// 构建日志里打印了密钥
// 外部 PR 能读到 secrets
// 3. 工作流注入
// PR 标题、描述里的命令
// 被 CI 系统执行
// 4. Action 投毒
// 第三方 Action 被攻破
// 所有用它的项目都受影响
// 5. 权限提升
// 从 PR 环境
// 提升到主分支发布权限
6.3 暴露面分级
| 暴露级别 | 情况 | 风险 |
|---|---|---|
| 严重 | 外部 PR 能在 runner 上 RCE | secrets 全泄露 |
| 高 | 外部 PR 能读到 secrets | 密钥泄露 |
| 中 | 只能影响构建结果 | 投毒包风险 |
| 低 | 信息泄露 | 辅助攻击 |
七、防护建议
- 升级 Claude Code Action:升级到 1.0.74 以上版本
- 检查 workflow 配置:不要对外部 PR 自动运行高权限 Action
- 最小权限原则:runner 只授予必要的 secrets,不要全量注入
- 人工确认触发:外部 PR 的 AI 审查需要维护者手动触发
- 固定 Action 版本:用 commit hash 固定 Action,不要跟踪分支
- 定期审计 CI/CD:检查 secrets 权限、workflow 触发器、第三方 Action
八、总结
CVE-2026-47751 是 AI 时代 CI/CD 安全的一个典型案例:当 AI 编码代理进入了 CI/CD 流水线,安全模型就变了------传统的"PR 代码不可信"假设,在 AI 代理自动读取项目配置、自动启动工具进程的新模式下,变得极其脆弱。随着 AI Agent 越来越多地进入开发流程,"信任边界"会变得越来越模糊:什么是受信任的代码?什么是受信任的配置?什么是受信任的工具?这些问题,在 AI 编码代理普及之前,很少有人认真思考过。在 SRC 挖洞实践中,CI/CD 供应链是越来越重要的方向------一个开源项目的 CI/CD 被攻破,影响的可能是成千上万个下游用户。
