Product1 publisher3 min readPublished
A fake branch name defeats the commit pin four AI coding agents rely on
Air Security's Plugin4Shell lets a plugin be swapped during a background refresh while the agent reports the audited commit. Anthropic and OpenAI have patched, Copilot has no fix, and Google is retiring Gemini CLI.
The Product Desk · Product desk

What happened
- Air Security published a flaw it calls Plugin4Shell on Thursday, covering Anthropic's Claude Code, OpenAI's Codex, GitHub Copilot and Google's Gemini CLI, and its researchers call it zero-click remote code execution.
- The agents ask for a plugin's pinned commit hash but never check what arrives, and git quietly prefers a branch when a name is both a valid branch and a valid object.
- Anthropic fixed it in Claude Code 2.1.179 and OpenAI in Codex 0.146.0, while Microsoft has shipped nothing for Copilot and Google will not fix Gemini CLI because it is retiring the tool.
- GitHub told The Register that its rejection of hash-shaped branch names stops exploitation on its platform, and Air replies that Bitbucket and self-hosted git servers allow such names.
Compiled by The Product DeskSomething wrong?How this is made
Why it matters
- decision Organise the pass by marketplace host and refresh setting, because the exploit needs a repository host that accepts hash-shaped branch names and background updates turned on for it.
- exposure Copilot customers carry the residual risk, since the agent Microsoft says nearly the whole Fortune 500 uses is one of the two with nothing to install.
- constraint Gemini CLI users have no upgrade path to wait for, so removing the tool or its plugins is the only control left to them.
- contradiction A team that reads only GitHub's statement will close the ticket, while Air's account leaves open the internal catalogues on Bitbucket and company git servers that Anthropic's documentation supports.
Claude Code and Codex refresh installed plugins in the background by default [13]. Air's sequence begins with a plugin that is genuinely useful, passes review and collects users, followed by a routine update that makes the marketplace re-pin it to a fresh commit [14]. Then whoever controls the repository creates a branch whose name is that hash, points it at other code and makes it the default. Git prefers the branch, the agent installs what the branch holds without comparing the pin against what landed on disk [8], and the install is logged as clean at the pinned commit [9][10].
Air's researchers describe a plugin as running with the same access as the person using the agent, which covers that person's files, their stored credentials and every system they can log in to [15]. OWASP moved excessive agency to third place in its 2026 top ten this month [16].
How far this reaches depends on where the repositories sit. GitHub rejects branch names shaped like commit hashes, and a GitHub spokesperson told The Register that this mitigation stops anyone exploiting the vulnerability on GitHub [17]. Swati Khandelwal at The Hacker News checked the shipped marketplaces on 18 September and found every plugin in the default Claude Code and Copilot catalogues, and in Anthropic's community catalogue, pointing at a GitHub repository [21]. Background refresh runs by default only for those built-in catalogues, and for outside marketplaces it is off or optional [22].
Sorting an estate comes down to where each marketplace's code lives and whether background refresh is enabled for it. GitHub with refresh on is covered [17][22]. Bitbucket or a company's own git server with refresh on is what Air describes, and Anthropic's documentation lists both as valid marketplace backends [18][2]. A team that stood up an internal plugin catalogue on its own git host is already there. Switching refresh off removes the zero-click part and leaves the swap, because the checkout that never verifies its result is the same one a hand-run update performs [8].
Copilot supports those same hosts, and Air locates the exposure there, while Microsoft has shipped no fix [19][5]. Microsoft's own figure puts Copilot in roughly 90% of Fortune 500 companies [20]. Microsoft did not respond to The Register [19].
Gemini CLI fails differently. It fetches the correct commit, then runs a checkout that a default branch named FETCH_HEAD can capture, so the right code never reaches the disk [11]. GitHub's branch-name rule does not clearly block FETCH_HEAD [23], and Google will not patch the tool because it is being retired [6].
The correction Air describes is one line: after the checkout, resolve what is actually in the working tree and abort unless it matches the pin [12]. Anyone who wrote an internal agent, or a wrapper around one of these marketplaces, should be asked whether it does that. For Claude Code and Codex the patch is two version bumps [4]. The list itself takes longer: one row per marketplace, with its host and its refresh setting written next to it.
What to watch
- Whether Microsoft ships a Copilot fix or treats GitHub's branch-name rule as its answer for Bitbucket and self-hosted marketplaces.
- Whether Bitbucket or self-hosted git vendors start rejecting hash-shaped branch names, and whether anyone blocks FETCH_HEAD as a branch name.
- Whether Google publishes guidance for Gemini CLI plugin users given that it will not patch the tool.