深海军蓝背景上的抽象技术插图:左侧边缘矗立着一块高大的半透明边界平面,以浅淡的细轮廓线绘制,内部为磨砂填充。一条白线穿过它,向右延伸,穿过四个相同的发光青色模块,这些模块呈浅弧形排列,每个模块上方都悬浮着一个相同的白色六边形徽章。第三个模块向左移动了半步,在原先所在的位置留下淡淡的浅色残影轮廓,其上方的六边形徽章发出琥珀色光芒。图中没有文字、人物或组织标识。OrcaRouter 标志合成在右下角。
AI Safety Incidents

Plugin4Shell:四个 AI 编程智能体信任了一个它们从未检查过的 Pin

作者

Alistair Wren

发布日期

最新模型 · 20查看全部模型 →
基准测试:Artificial Analysis · 每日更新
返回全部文章

2026年9月17日,AIR Security——一家为企业级AI代理构建安全工具的初创公司——发布了一项研究,描述了 Plugin4Shell:一个影响四款AI编程代理的零点击远程代码执行漏洞,涉及 Anthropic 的 Claude Code、OpenAI 的 Codex、GitHub Copilot 以及 Google 的 Gemini CLI。该漏洞并不存在于任何模型中,而是出在每款代理安装插件时所执行的 git 检出环节,以及这样一个事实:这四款代理无一验证过它收到的代码就是它当初锁定的代码。研究公开时,四款中有两款已发布补丁,另两款则没有。本次事件是Orca AI 事件档案中的一条记录,该档案将其记录为一起高危供应链漏洞,且未报告存在任何利用行为。

这些代理实际做错了什么

每个受影响的 agent 都会从市场安装插件,而一旦插件经过审查,每个市场都会把该插件固定到一个特定的 git 提交——一个 40 个字符的 SHA。这个固定就是整个安全模型的核心:审查者批准的是一个不可变版本,而 agent 本应持续运行该版本,即使其背后的仓库之后发生变化。AIR 将这一缺陷描述为插件 SHA 固定绕过。agent 会检出市场所固定的确切提交,但从不验证它最终得到的工作树就是该提交。用研究人员的话说,agent“检出了市场所固定的确切提交,却从不验证它是否真的落在那里,因此控制插件仓库的攻击者可以让检出解析到恶意代码,而固定看起来仍然得到了遵守。”

Git 正好补上了这个缺口。当一个名称既是有效分支名又是提交对象时,git 会优先选择分支,只打印一条歧义警告。控制插件仓库的攻击者可以创建一个名称恰好为 40 位十六进制固定 SHA 的分支,将其指向恶意代码,并使其成为仓库的默认分支。随后,普通克隆会在本地以这个 SHA 形状的名称拉取该分支,接下来的 checkout 就会解析到它。被固定的提交本身可以保持不动,因此受审查版本的一切看起来都没有问题。根据 AIR 的说法,必须满足两个条件:以 SHA 命名的分支必须是默认分支,因为非默认分支只会作为远程跟踪引用被获取,checkout 会回退到真正的提交;并且 git 主机必须接受 40 位十六进制分支名。GitHub 会直接拒绝这类名称。Bitbucket 和自托管的 git 服务器则不会。

Gemini CLI 经由另一条路径失败了。它获取了固定的提交,将其记录在仓库的 FETCH_HEAD 文件中,然后对 FETCH_HEAD 执行检出——这种检出不必读取该文件。若某个仓库的默认分支本身就叫 FETCH_HEAD,就会把检出重定向到攻击者控制的内容,并静默丢弃已获取的提交。Cybersecurity News 对该机制的描述与 AIR 的一致,包括对两种变体之间区别的说明。

为什么没人需要点击任何东西

同一个 checkout 会在后台插件自动更新期间再次运行,而这在 Claude Code 和 Codex 中是默认行为。这正是该攻击成为零点击、而不只是悄无声息的原因:当某个市场把固定的 SHA 提升为常规的新版本时,每个已安装该插件的 agent 都会在没有任何提示、也没有用户操作的情况下重新运行 checkout。AIR 的要点是,受害者不需要粗心安装任何东西。他们只需要安装过一个插件,来自他们信任的市场,并且该插件完全按照设计意图经过审查和固定。

要达到那个位置有两种方式,而两者都不需要控制市场。第一种,攻击者发布一个真正无害的插件,让它通过审核、积累安装用户群、发布正常更新,然后才创建那个恶意命名的分支。第二种,攻击者接管别人编写且市场已经信任的插件背后的仓库,然后把恶意版本推送给所有已安装该插件的人。

这两条路径背后的数字来自 AIR 早先的研究,而非 Plugin4Shell。在该公司称为“The Story of Skills”的行动中,它表示其构建的一个插件在被撤下前已传播到超过 26,000 个智能体。在 SkillJacking 中,它报告称,已有 925 个处于活跃使用状态的技能被从原始维护者手中接管,波及 134,000 个智能体。AIR 在 Plugin4Shell 帖子中的标题声称“数百万个智能体受到影响”;该研究未给出暴露安装数量的统计,也没有第三方公布过这一数字。

时间线,以及各项修复落地的位置

HTML card headed 'Six weeks from proof of concept to public' with kicker 'Plugin4Shell · AIR Security · disclosure sequence'. A vertical timeline in cyan lists six dated entries: May 2026, working proof-of-concept against all four agents; June 2026, coordinated disclosure to Anthropic, OpenAI, Google and Microsoft; 17 June 2026, Anthropic confirms the fix in Claude Code 2.1.179; 4 August 2026, Google confirms no fix will ship because Gemini CLI is being deprecated; 12 August 2026, Codex 0.146.0 verified fixed; 17 September 2026, AIR Security publishes the research. A seventh entry in amber marks 18 September 2026, when The Register, Help Net Security, InfoWorld and Cybersecurity News reported it. An amber box headed 'Still open at publication' records that no CVE identifier had been assigned, no vendor security advisory had been published, and no source answers whether updating an affected agent removes a plugin that has already been swapped. A footer cites the AIR Security disclosure timeline and the outlets that reported it. The OrcaRouter logo is composited in the bottom-right corner.

AIR 表示,它于 2026 年 5 月发现了该漏洞,并针对全部四个代理都制作了可用的概念验证漏洞利用程序,随后在次月依据协同披露原则向各厂商披露。Anthropic 于 6 月 17 日确认已在 Claude Code 2.1.179 中修复。Google 于 8 月 4 日告知 AIR 不会发布修复,因为 Gemini CLI 正在退役。Codex 0.146.0 已于 8 月 12 日验证修复。Microsoft 尚未为 GitHub Copilot 发布修复。

补丁版本是唯一公开确认该漏洞在这两个已修复它的产品中确实存在的依据。Anthropic 发布的 2.1.179 变更日志条目列出了连接中断处理、WSL2 滚动、沙箱 glob 和接口修复,但完全没有提到版本固定、插件验证或任何形式的安全修复。据 The Next Web 的报道,The Hacker News 也观察到了同样的情况。截至该研究发布时,尚未分配 CVE 标识符;Cloud Security Alliance 关于该漏洞的研究说明还再次指出,在通知供应商三个月后仍不存在标识符。

四家供应商,三种不同答案

HTML card headed 'One flaw, four agents, two patches' with kicker 'Plugin4Shell · vendor status at disclosure · 17 September 2026'. A four-row table gives agent, vendor, status and mechanism variant: Claude Code from Anthropic, fixed in 2.1.179 on 17 June 2026, branch named as the pinned SHA; Codex from OpenAI, fixed in 0.146.0 and verified on 12 August 2026, same branch variant; GitHub Copilot from Microsoft, no fix shipped at disclosure, same branch variant; Gemini CLI from Google, no fix and the product deprecated as of 4 August 2026, separate FETCH_HEAD variant. A note beneath reads that the branch-named-as-a-hash variant needs a git host that accepts a 40-character branch name, which GitHub does not and Bitbucket and self-hosted git do, that background auto-update is on by default only for Claude Code and Codex, and that Antigravity, the replacement Google points to, has no marketplace plugin SHA pinning to bypass. A footer cites AIR Security, The Register and Help Net Security. The OrcaRouter logo is composited in the bottom-right corner.

谷歌做得比拒绝修补更进了一步。它弃用了 Gemini CLI,这意味着只要人们继续运行现有安装,这些安装就会一直处于暴露状态。它的建议是迁移到 Antigravity——更新的智能体开发环境;AIR 表示,该攻击无法触及它,因为它没有可被绕过的市场插件 SHA 固定机制。

GitHub 的立场又有所不同。一位 GitHub 发言人告诉 The Register,该平台不允许用户创建类似提交 SHA 的分支或标签名称,并且“这一缓解措施确保所报告的漏洞无法在 GitHub 上被利用”。AIR 质疑的是这一缓解措施的范围,而非其是否存在:研究人员告诉 The Register,市场可以托管在 Bitbucket 等其他平台上,而 GitHub Copilot 仍然支持来自这些平台的市场,因此对于 Copilot 用户来说,分支名称这一变体仍然可达。AIR 还表示,Anthropic 自己的文档将 Bitbucket 和自托管 git 列为有效的市场后端;Anthropic 当前的市场文档描述的是从 git 仓库 URL 添加市场,而不只是从 GitHub 添加。微软未回应 The Register 的置评请求,AIR 表示自 6 月报告该问题以来一直未收到微软的回复,并提到该公司正在处理的披露数量之多。

这是关于暴露范围有多大的分歧,而不是关于漏洞是否存在的分歧。GitHub 的缓解措施是主机层面的限制;AIR 的发现是,检查必须在 agent 内部进行,因为 pin 是在客户端解析的。

哪些是已确立的,哪些不是

• 已确认:该机制。AIR 的说明给出了确切的 git 命令、ref 优先于 object 的解析规则、分支技巧所需的两个条件,以及针对 Gemini CLI 的单独 FETCH_HEAD 变体。The Register、Help Net Security、Cybersecurity News、InfoWorld 和 The Next Web 均以相同方式报道了此事。

• 已确定: 两个修复版本。根据 AIR 的披露时间线,Anthropic 于 2026 年 6 月 17 日确认了 Claude Code 2.1.179,OpenAI 的 Codex 0.146.0 也于 2026 年 8 月 12 日被验证已修复。

• 已确认:披露时有两个产品尚无补丁。Google 不会为 Gemini CLI 提供补丁,并正在将其停用;Microsoft 尚未发布 Copilot 的修复程序。

• 未确立:独立复现。所有已发表的记述都可追溯到 AIR 自己的博客文章,而 Cloud Security Alliance 的研究说明明确未描述对该漏洞利用的第三方技术验证或独立复现。正因如此,档案将这条记录的置信度评为 B。

• 尚未确定: 实际有多少个安装实例被暴露。“数百万”是 AIR 在其标题中的表述,并非实测数字。

• 尚未确定:更新受影响的代理是会移除已经换上的插件,还是只会阻止下一次换入。尚无公开来源对此给出定论。

• 未获证实:任何现实世界中的利用。记录中没有任何来源报告过漏洞利用、探测或攻击者基础设施,且档案将实际危害记录为不实。这只能说明缺乏相关报告,并不能证明什么都没发生。

一项第三方核查确实缩小了实际影响范围。The Next Web 在总结 The Hacker News 的核查时报道称,Anthropic 社区目录以及 Claude Code 和 Copilot 默认目录中的插件都指向 GitHub 仓库,而且自动更新主要针对这些内置市场默认开启。由于 GitHub 拒绝形如 SHA 的分支名,对于仍使用默认目录的用户来说,分支名变体更难被触发。这一推理并不涵盖 Gemini CLI 的 FETCH_HEAD 变体,因为该变体不依赖于主机如何命名分支。

修复必须是什么样子

Abstract technical illustration on a dark navy field: a white hexagonal badge floats at the top centre, and from it a single white line descends through three translucent horizontal planes, passing through the middle of each. At the lowest plane the line passes a small hollow white ring, then splits — one branch continues straight down to a filled white dot on the plane, the other turns amber and runs off to the left, ending at a small dark unlit block that sits outside the stack. A faint pale outline of that block is drawn on the plane where it should have sat. No text, people or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.

AIR 建议的修复方案只有一条断言:检出之后,解析工作树中实际存在的提交,除非它等于固定的 SHA,否则中止。研究人员强调,必须检查解析后的 HEAD,而不是所请求的 ref,因为这一区别正是 Gemini CLI 变体得以绕过的关键;并且这项检查必须在智能体内部运行,因为固定值是在客户端解析的,没有任何市场能够强制执行其宣称的保证。

为运行这些智能体的团队提供实用建议,内容摘自 AIR、Cybersecurity News 以及 InfoWorld 中的分析师评论:

• 将 Claude Code 更新至 2.1.179 或更高版本,并将 Codex 更新至 0.146.0 或更高版本。在存在补丁的情况下,更新是唯一完整的缓解措施。

• 在任何没有补丁的代理上禁用插件自动更新。这将该漏洞从零点击利用降为需要手动重新安装,这只是在减少暴露面,而不是修复。

• 从 Gemini CLI 迁移出去,而不是等待 Google 已表示不会推出的补丁。

• 审计插件清单,并在可能的情况下限制市场来源。AIR 指出,市场可以通过仅允许会拒绝 SHA 形式名称的托管方,来抑制分支名变体,实际上等同于仅限 GitHub;但这会禁止代理官方支持的托管方,并且对 Gemini 变体毫无作用。

• 将工作站视为暴露边界。插件会继承代理的权限,因此一次成功的利用就能以开发者本人的权限触达源代码、SSH 密钥、云凭证、CI/CD 令牌和内部代码库。Pareekh Consulting 首席分析师 Pareekh Jain 对 InfoWorld 表示,安全团队应查看 EDR、git、CI/CD、云 IAM 和身份验证日志,寻找异常进程、意外的插件文件、被更改的代码库以及可疑的 git 活动——并补充说,这些步骤可以降低风险,但无法修复底层缺陷,他将该缺陷归因于供应商代码。他对 InfoWorld 说:“企业可以围绕插件使用设置控制措施,但无法修复编码代理在验证其检出的代码时所存在的缺陷。”

为什么一个与固定相关的缺陷才是真正重要的那个

SHA 固定(SHA pinning)正是业界针对 AIR 此前已演示过的那类接管攻击给出的解决方案:如果公共仓库被攻陷,代理会继续运行经过审计的哈希,而不是拉取攻击者推送的任何内容。Plugin4Shell 并没有攻破哈希本身。它表明的是,代理把这个固定值解析成了一个仅仅看起来像该哈希的分支名,并且从未核对解析结果。基于这一假设的下游一切——审查流程、内部允许列表、开发者对固定版本所抱有的信心——都继承了这个失效。

记录无法支持的是这样一种说法:有任何东西被拿走了。这是一个已被发现、并且在四起案例中的两起里得到修复的漏洞;其中没有任何来源报告过入侵,而那些未发布补丁的产品仍在等待。悬而未决的问题最不令人满意:对于任何在未打补丁的代理程序上运行过插件的人,都没有公开途径来判断实际运行的代码是否就是他们批准过的代码。