ARTICLE · 1073610
你装的 AI 编程助手,可能正在被别人远程执行代码
上周我照常打开电脑,终端里那个 AI 编程助手在后台自己更新了几个插件。
它一直是这样。默认开启,不需要我确认,也不用点任何东西。我一直以为这件事是安全的——因为插件的版本被"钉"在了一个 commit 哈希上:市场审核过那份代码,把哈希写进配置,此后的每一次安装和更新,都只会拉到那一个版本。
这是我理解里的标准答案。也是整个软件行业花了十几年才学会的做法。
直到我读完 9 月 17 日那份披露。

先说结论:四家里,两家已经不修了
漏洞叫Plugin4Shell,由安全公司 Air Security 披露。影响四个主流 AI 编程助手:Anthropic 的 Claude Code、OpenAI 的 Codex、微软的 GitHub Copilot、Google 的 Gemini CLI。
修复状态是这样的:
Claude Code:已在 2.1.179 修复 OpenAI Codex:已在 0.146.0 修复 GitHub Copilot:至今未发布补丁 Gemini CLI:产品已废弃,Google 确认不予修复,建议用户迁移
四个里,两个修了,两个没修。注意,不是"还没来得及"——从通报到公开披露,中间隔了三个多月。
还有一个细节值得留意:Claude Code 2.1.179 的发布说明里,并没有提到这次修复。修复这件事,是从 Air Security 的披露里才知道的。

少的是哪一行校验
先说清楚"钉版本"这件事为什么重要。
插件市场有一套标准流程:插件提交上来,人工评审,评审通过之后,把那个版本的 commit 哈希记下来(也就是 SHA pinning)。之后 agent 每次安装或更新,都按这个哈希去拉代码。
这套机制的用意是防"卷毯攻击"(Rug Pull)——插件作者可以在你信任他之后,悄悄把仓库里的代码换成恶意的。但只要你装的是那个被钉住的版本,换不换都影响不到你。
锚定的是哈希,哈希指向的是一个不可变的 commit 对象。这是整个信任链条的地基。
Air Security 发现的问题是:四个 agent 在检出(checkout)钉住的 commit 之后,没有一个去验证工作区里真正落地的代码,到底是不是那个 commit。
缺的就是一行校验——解析当前工作区的真实 HEAD,跟钉住的 SHA 对不上就中止。
就因为缺了这一行,Git 自身的一条既定行为变成了攻击通道。

Git 里有一条规则:当一个名字既是合法的引用(ref),又是对象 ID 时,git checkout 会优先解析为引用。它只往 stderr 打一条 refname is ambiguous 的警告——而在 agent 的自动化流程里,没有人会去看这条警告。
所以攻击方式就是:在插件的上游仓库里,建一个名字恰好等于那 40 位哈希的分支。
然后把它设为默认分支,内容指向恶意代码。
普通 git clone 会把默认分支拉成本地分支。等到 agent 执行 git checkout a1b2c3d4... 的时候,这个名字同时匹配一个本地分支和一个 commit 对象,Git 取了分支——恶意代码落地,而 agent 依然报告"已按钉住版本成功安装"。
而那个被钉住的 commit 本身,可以原封不动地留在仓库里。仓库历史看起来完全正常。
Gemini CLI 是另一个变体:它的流程是先 git fetch 拿到正确的 commit,再 git checkout FETCH_HEAD。攻击者只需要把默认分支命名为 FETCH_HEAD,刚取回来的正确 commit 就被静默丢弃了。
有个分界点值得一提:GitHub 会拒绝创建形似 commit 哈希的分支名,所以托管在 GitHub 上的插件不受第一个变体影响。但Bitbucket 和自建 Git 服务器允许这类名字——而这两个,恰恰是 Anthropic 官方文档里明确支持的插件市场后端。
为什么它是"零点击"的
很多远程代码执行漏洞需要骗你做一个动作:点开链接、装个插件、批准一个弹窗。
这个不需要。关键在于一个普遍存在的默认行为:Claude Code 和 Codex 里,已安装插件的后台自动更新是默认开启的。
这意味着攻击者不需要说服任何人装新东西。他只需要:
提交一个真正无害的插件,通过评审,积累装机量 正常更新一次,市场把钉住的哈希挪到新 commit 在上游仓库建一个同名分支,指向恶意代码 哈希变更自动触发所有已安装 agent 的更新,检出拐向分支
受害者唯一"做错"的事,就是按照安全模型所期望的方式,正确地使用了一个受信任的市场。
而插件继承的是运行者的全部权限:本地源代码、云服务凭证、SSH 私钥、内部仓库、生产环境的访问通道。一次成功的利用,等于把开发者本人的数字身份整个交出去。
公平地说一句:截至披露日,没有分配 CVE 编号,也没有确认的野外利用案例。
三件事,今天就该做

第一步,查版本。Claude Code 升到 2.1.179 以上,Codex 升到 0.146.0 以上。Copilot 没有补丁可用,先别用非 GitHub 托管源的插件。Gemini CLI 建议直接迁走。
第二步,查插件来源。你的插件托管在哪?如果是 Bitbucket 或者自建 Git,那就在第一个变体的射程之内。
第三步,想清楚自动更新这件事。它是"零点击"的成因。补丁落地之前,可以考虑先关掉。
最后有一个容易忽略的点:披露信息里并没有说明升级会自动清理已被替换的插件。升级只挡住未来的偷换。如果你怀疑自己在攻击窗口内暴露过,稳妥的做法是升级之后,从可信来源把插件重装一遍。
这件事让我有点在意的,不是漏洞本身。
是那个缺失的校验实在太朴素了——朴素到你会以为"这不可能没人写"。但四个不同团队、四个不同代码库,同一个设计错误被复制了四遍。
安全圈有一句老话:审核一次代码,锁定它的哈希,此后永远运行这个被审核过的版本。这句话在过去十年里基本成立。
现在它多了一个前提:得有人低头确认过,落地的是哪一个。
一手出处
Air Security 研究实验室(Or Nevo、Dor Granat、Niv Hoffman),2026-09-17 公开披露 Cloud Security Alliance Labs 研究笔记:Plugin4Shell: SHA-Pinning Bypass Enables AI Coding Agent RCE heise online:Critical flaw in Claude Code, OpenAI Codex, GitHub Copilot and Gemini CLI 版本与时间线:Claude Code 2.1.179(2026-06-17 确认修复)/Codex 0.146.0(2026-08-12 验证修复)/Gemini CLI(2026-08-04 确认不予修复)
我排除了哪些数字
网上流传的"影响上百万开发者""已被大规模利用"——没有信源支持。截至披露日无 CVE 编号、无野外利用确认,请不要引用这类说法。 那 925 个被劫持 Skill、26,000 个受影响 agent 等数字来自 Air Security 此前的另一项研究(SkillJacking / RepoJacking),不是本次漏洞的数据,混用会出错。