Plugin4Shell: a fake branch beats pinning in AI coding agents
A git trick swaps pinned plugin code in Claude Code, Codex, Copilot and Gemini CLI with zero clicks. Copilot and Gemini CLI remain unfixed.
By Yaali. September 28, 2026, 6 min read, Vulnerabilities, Threat intel.
On September 17, AIR Security disclosed Plugin4Shell, a flaw in the plugin systems of four AI coding agents: Anthropic's Claude Code, OpenAI Codex, GitHub Copilot and Google's Gemini CLI. Each lets a plugin marketplace pin a plugin to one reviewed commit, and in each, whoever controls the plugin's repository could swap that commit for different code. The swapped code installs and runs with no prompt, no click and no warning to the developer, which makes this a zero-click remote code execution (RCE) flaw.
Patching is uneven. Anthropic fixed Claude Code in version 2.1.179 and OpenAI fixed Codex in 0.146.0, both before disclosure. As of September 28, GitHub Copilot still has no client fix, and Google has said it will not patch Gemini CLI because the tool is being retired. No CVE has been assigned, and The Next Web found no vendor advisory, so there is nothing for a vulnerability scanner to match on. If your developers install agent plugins from marketplaces, you need to check which agent and which git host each one uses.

How it works
A git commit hash (SHA) is a 40-character hexadecimal fingerprint of an exact snapshot of code. Plugin marketplaces for these agents list each plugin as a repository URL plus a pinned SHA, the same idea as pinning a dependency to a version in a lockfile. The pin is meant to guarantee that the code a developer runs next month is byte for byte the code someone reviewed, even if the plugin's author later pushes changes.
The agents then fetch the plugin with ordinary git commands. According to AIR, Claude Code, Codex and Copilot run git clone followed by git checkout <pinned sha>. Gemini CLI does a shallow clone, then git fetch origin <pinned sha> and git checkout FETCH_HEAD. None of the four then checked that the commit it ended up on was the one it asked for.
That missing check is the whole bug. Git lets you name a branch almost anything, including a 40-character hex string. When a name passed to git checkout matches both a branch and a commit hash, git picks the branch. So the repository owner creates a branch named exactly after the pinned SHA, puts different code on it and makes it the default branch. The agent asks for the reviewed commit, git hands it the branch, and the pin in the marketplace still shows the approved hash.
The trick depends on the git host. GitHub rejects branch and tag names that look like a full commit hash, which blocks the demonstrated variant for plugins hosted there. AIR says Bitbucket and any self-hosted git server allow them, and heise also lists GitLab, a point AIR's own write-up does not make. AIR points out that Anthropic's documentation lists Bitbucket and self-hosted git as valid marketplace sources, so this is a supported setup.
Zero-click comes from automatic updates. Claude Code and Codex update plugins in the background by default, and each update runs the same checkout again. When the marketplace moves a plugin's pin to a newly reviewed commit, the attacker's branch with that name is already waiting, and the agent installs it without asking anyone. Plugins run with the developer's own privileges, so the code can read local files, SSH keys, cloud credentials and tokens for any system the developer's machine can reach.
What attackers are doing
AIR researchers Or Nevo, Dor Granat and Niv Hoffman found the flaw in May 2026 and built working proof-of-concept exploits. They reported it to all four vendors in June under coordinated disclosure. Anthropic's fix was confirmed on June 17 (heise dates it June 16), Google told the researchers on August 4 that it would not patch Gemini CLI, and OpenAI's fix was verified on August 12. heise reports no confirmed use of the technique in the wild.
The attacker has to control the plugin's repository, or be able to push branches to it. That covers a malicious plugin author, a compromised maintainer account and a repository whose ownership changed hands. The same team has already shown how far a hijacked add-on travels in this ecosystem: an earlier AIR study tracked one malicious skill to about 26,000 agents, and its SkillJacking research found 925 hijacked skills reaching about 134,000 agents.
A realistic chain looks like this. The attacker publishes a useful plugin on Bitbucket or a self-hosted git server and submits a clean commit for review. Because they wrote that commit, they know its hash before anyone approves it, and they create a default branch with the same name holding malicious code. The marketplace reviews the clean commit and pins it, and every developer who then installs the plugin, or whose agent auto-updates it, runs the branch instead with nothing on screen to show it.
GitHub told The Register that its service does not allow SHA-like branch or tag names. AIR's answer is that Copilot marketplaces can live on other hosts, and that the pin is resolved on the developer's machine, so no marketplace can enforce it and the fix has to ship in the agent.
What to do

1. Update Claude Code and Codex
Run claude --version and codex --version on every developer machine and build runner that has them. Claude Code must be 2.1.179 or later and Codex 0.146.0 or later. Where installs are managed centrally, also check the version your package list or base image pins.
2. Cut GitHub Copilot's exposure until Microsoft ships a fix
There is no fixed Copilot version to deploy. Remove any plugin marketplace whose source is on Bitbucket or a self-hosted git server, since GitHub's refusal of hash-shaped branch names is what blocks the demonstrated attack. Turn off automatic updates for third-party plugins where the client allows it, so a new pin cannot pull in a swapped branch while nobody is watching.
3. Plan the move off Gemini CLI
Google announced the retirement on May 19, before AIR's report, and stopped serving Gemini CLI to consumer accounts on June 18 in favor of Antigravity CLI. Organizations with Gemini Code Assist Standard or Enterprise licenses, or paid API keys, can keep running it, and those installs will not get a fix. Until you migrate, uninstall every extension whose repository is not on GitHub or not under your own control.
4. Check whether a swap already happened
For each installed plugin whose folder is a git checkout, run git rev-parse HEAD in it and compare the result with the SHA the marketplace pins. They should match exactly. For each plugin repository, run git ls-remote --heads <repo-url> and look for any branch whose name is 40 hex characters; a legitimate project has no reason for one. If you find a mismatch or such a branch, treat that machine as compromised: rotate the SSH keys, cloud credentials and tokens stored on it, and review what the plugin could reach.
5. Treat pinning as one control of several
A pin only protects you if the client checks the result. Prefer plugins from repositories your organization controls, and on self-hosted git, reject pushes of branch or tag names matching ^[0-9a-f]{40}$ with a server-side pre-receive hook. Keep a list of which plugins each team runs and where they are hosted, so that when the next plugin flaw is disclosed, that list tells you which machines to check.
Our red team and code review engineers test how your developer tooling, plugin sources and agent setup hold up against a hostile repository owner. Our AI-native systems team sets the permissions and update policies for coding agents before they reach every laptop. Open the chat and Yaali, our AI agent, will pass your question to the engineer who would do the work.
Sources: AIR Security, Plugin4Shell, Help Net Security, The Hacker News, The Next Web, heise online, AiCybr, Pasquale Pillitteri, Google Developers Blog, Transitioning Gemini CLI to Antigravity CLI.
Read next
- Three malicious PyPI packages and when their code runs
- Two NetScaler zero-days exploited: patch and check today
- Zyxel switch flaw exploited two months post-patch
Back to the blog, or tell us about your system in the chat. Yaali, our AI agent, answers first and brings in an engineer.