Pinned Means Pinned: Plugin4Shell Breaks the AI Coding Agent Supply Chain With Zero Clicks
Security firm Air disclosed Plugin4Shell, a zero-click RCE that silently swaps SHA-pinned plugins for malicious ones in Claude Code, Codex, Copilot and Gemini CLI. Anthropic and OpenAI shipped fixes in June; Microsoft and Google did not. Here is how the git ref-ambiguity trick works, who is exposed, and what to do this week.
On September 17, 2026, a security startup called Air (air.security) published research it had been sitting on since May: a working, zero-click remote code execution chain — dubbed Plugin4Shell — against all four of the most widely deployed AI coding agents: Anthropic’s Claude Code, OpenAI’s Codex, GitHub Copilot, and Google’s Gemini CLI. It is the first genuine supply-chain vulnerability native to the AI agent ecosystem: not a flaw in a model, not a prompt injection, but a break in the distribution layer underneath — the marketplaces through which plugins reach millions of developer machines.
The short version is uncomfortable. The industry’s standard defense against plugin tampering is SHA pinning: review the code at one commit, pin that exact commit hash, and trust that the pinned snapshot is what runs forever after. Plugin4Shell makes the agent check out the pinned commit but never verify that the pinned commit is what actually landed in the working tree. One missing assertion — and every major lab shipped it.
What actually breaks
Every affected agent installs plugins from a marketplace by cloning the plugin’s git repository and checking out the hash the marketplace pinned:
git clone <plugin repo> ./
git checkout aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Here is the trick. Git’s own git check-ref-format happily accepts a branch name that is a 40-hex string — the exact shape of a commit SHA — and so do some code hosts, notably Bitbucket and self-hosted git servers. So an attacker who controls the plugin’s upstream repository can:
- Plant — publish a genuinely benign plugin, pinned at commit
aaa…aaa. It passes review. - Adoption — thousands of agents install it, each pinned to
aaa…aaa. - Version bump — ship a routine, still-benign update; the marketplace re-pins to a new commit
bbb…bbb. - Rug-pull — create a branch named
bbb…bbb, set it as the repo’s default branch, and point it at malicious code. The original pinned commit can stay untouched. - Auto-update to RCE — the changed pin triggers every agent’s background auto-update. Because git resolves a ref in preference to an object ID of the same name (printing only a
refname is ambiguouswarning), the checkout silently lands on the attacker’s branch. No prompt, no click.
That last step is what makes it zero-click: plugin auto-update runs by default in Claude Code and Codex, so the swap reaches machines where the plugin is already installed and trusted. The attacker doesn’t need to persuade anyone to install anything new — they only need the benign plugin to already be there.
The Gemini CLI variant is uglier. It pins with git clone --depth 1, then git fetch origin <sha> and git checkout FETCH_HEAD. But git checkout FETCH_HEAD reads the branch named FETCH_HEAD if one exists and is the default branch — the fetched commit is silently discarded. And since GitHub’s rule against hash-shaped branch names doesn’t clearly block the name FETCH_HEAD, installing from GitHub doesn’t obviously save you here.
One bug, four vendors, three answers
Air found the flaw in May 2026, built working proofs-of-concept against all four agents, and disclosed to the vendors in June under coordinated disclosure. The response matrix is the story:
| Agent | Vendor | Status |
|---|---|---|
| Claude Code | Anthropic | Fixed in 2.1.179 (confirmed 2026-06-17) |
| Codex | OpenAI | Fixed in 0.146.0 (verified 2026-08-12) |
| GitHub Copilot | Microsoft | No fix shipped as of disclosure |
| Gemini CLI | Will not fix — CLI deprecated; users advised to migrate to Antigravity |
The Register quoted OpenAI’s own public fix describing the same underlying bug: git “can interpret a requested commit SHA as a branch name,” which can make a plugin source “materialize a different commit than the one it pinned.” The Hacker News independently reproduced the git behavior locally and noted that as of September 18 no CVE identifier had been assigned and none of the four vendors had published a security advisory. Anthropic’s release notes for 2.1.179 don’t even mention the fix — the account that it is fixed comes from Air.
The one-line fix, for the morbidly curious, is an assertion every agent should have shipped from day one:
test "$(git rev-parse HEAD)" = "<pinned-sha>" || abort
It has to check the resolved HEAD — not the ref that was requested — and it has to run inside the agent, because the pin is resolved on the client. No marketplace can enforce the guarantee it advertises. That asymmetry is the real finding: a marketplace can blunt the branch-name variant by only allowing hosts that reject SHA-shaped names (effectively GitHub-only), but that bans hosts the agents officially support — Anthropic’s own documentation lists Bitbucket and self-hosted git as valid marketplace backends — and does nothing for the Gemini CLI variant.
Who is actually exposed
Air’s numbers from its earlier research put the blast radius in perspective. In The Story of Skills, the team planted a malicious skill that passed security scanners and reached about 26,000 agents. In SkillJacking, they showed 925 skills already in use had been hijacked out from under their maintainers, affecting 134,000 agents, simply by taking over the repositories behind them. Plugin4Shell is the mechanism that turns those takeovers into silent code execution — the chain is proven end to end.
The exposure is not limited to careless users. Organizations that do everything right — review plugins, pin them to reviewed commits, trust the marketplace — inherit the failure, because the pin itself is what’s broken. A swapped plugin runs with the full access of the person using the agent: their files, their saved credentials, every system they can log in to.
The Hacker News added useful nuance after checking the default marketplaces on September 18: every plugin in Anthropic’s community catalog, and in the default catalogs for Claude Code and Copilot, points to a GitHub repository — and GitHub rejects hash-shaped branch and tag names. Auto-update, meanwhile, is on by default only for the agents’ built-in GitHub-hosted marketplaces. So a developer who installs only from the default GitHub-based catalogs is largely shielded from the branch-name variant. The risk concentrates in non-default marketplaces and non-GitHub hosts — Bitbucket, self-hosted git — which are supported configurations, not edge cases.
Why this matters beyond the patch queue
Three things make Plugin4Shell more than a bad week for four product teams.
It’s a class bug, not an implementation slip. The same missing verification sat in four independently built agents from four competing labs. That is a design-pattern failure in how the young agent ecosystem inherited git semantics it didn’t fully audit. Every agent framework building a plugin system after this should treat “verify the checkout equals the pin” as table stakes — and every security review should ask for it by name.
The remediation model is broken. No CVE, no vendor advisories, fixes shipped silently in June with the disclosure held until September, and two of four vendors choosing not to fix at all. Enterprises that learned to triage risk by CVE feed had nothing to triage here. If agentic supply-chain flaws are going to be disclosed this way, defenders need new instruments — and vendors need to understand that “we deprecated it” is not a patch.
It lands right as agents got dangerous. 2026 is the year enterprises went all-in on coding agents, exactly as Air notes in its own coming-out-of-stealth post. Agents now hold credentials, write production code, and run on developer laptops with broad filesystem access. A supply-chain primitive that converts “control one upstream repo” into “execute arbitrary code on every machine that trusts it” is the agentic equivalent of the npm/PyPI typosquatting era — except the packages install themselves.
What to do this week
- Claude Code: update to 2.1.179 or later. Note that Anthropic’s release notes don’t call the fix out, so don’t wait for a banner — just update.
- Codex: update to 0.146.0 or later.
- Copilot: no patch exists. If your teams install plugins from non-GitHub hosts, treat those plugins as untrusted until Microsoft ships a fix — or disable third-party plugin sources.
- Gemini CLI: assume it will never be fixed. Migrate to Antigravity, which the attack cannot reach because it has no marketplace plugin SHA pinning to bypass.
- Everyone: inventory which marketplaces and git hosts your agents actually pull from. The GitHub-only default catalogs are the safe zone; anything else is the exposed surface.
- Builders of agent frameworks: ship the assertion. After checkout, resolve the commit actually in the working tree and abort unless it equals the pin. One line closes both variants.
The uncomfortable takeaway is that “pinned” was a promise no agent actually kept. Plugin4Shell didn’t break the pin — it revealed the pin was never really there. The fix is trivial; the trust rebuild won’t be.
Sources
- [1] https://www.air.security/blog-posts/plugin4shell
- [2] https://thehackernews.com/2026/09/plugin4shell-lets-repository-owners.html
- [3] https://www.theregister.com/security/2026/09/17/ai-coding-agents-0-click-rce-flaw-could-hand-attackers-keys-to-the-kingdom/5297335
- [4] https://www.helpnetsecurity.com/2026/09/18/plugin4shell-ai-coding-agents-vulnerability/
- [5] https://cybersecuritynews.com/plugin4shell-zero-click-rce/
- [6] https://www.infoworld.com/article/4223907/a-zero-click-rce-flaw-in-ai-coding-agents-could-have-exposed-enterprise-systems.html