What Actually Happened
On September 18, 2026, researchers at Air Security published Plugin4Shell, a zero-click remote code execution flaw affecting the four most widely used AI coding agents: Anthropic Claude Code, OpenAI Codex, GitHub Copilot and Google Gemini CLI.
The flaw does not live in a model. It lives in two lines of git plumbing that every one of those agents got wrong in the same way.
Plugin marketplaces lock a reviewed plugin to a specific 40-character commit hash. The hash is the security control: a commit hash is content-addressed, so pinning to one is supposed to mean the code can never change underneath you. Air found that all four agents request the pinned commit and then never verify that the working tree they ended up with actually matches it.
Anyone who controls the plugin repository can exploit that gap. No click, no reinstall, no approval prompt, no new permission. The next routine auto-update is enough, and auto-update is on by default in Claude Code and Codex.
How SHA Pinning Was Supposed To Work
Every plugin or skill marketplace serving AI agents follows roughly the same model. A plugin is published, someone reviews it, and the approved version is recorded as a git commit hash. From then on, installs and updates reference that hash rather than a branch or a tag.
That design is borrowed straight from software supply chain security, and it is the right design. A branch moves. A tag can be re-pointed. A commit hash is derived from the content itself, so it is immutable by construction. Pin to the hash and you have pinned the code.
That is the theory. The implementation is where it fell apart.
The Exploit: Git Resolves a Name Before It Resolves a Hash
Variant 1: A Branch Named Like a Commit Hash
Claude Code, Codex and GitHub Copilot install a plugin with the pattern every developer has typed a thousand times: clone the repository, then check out the pinned commit.
The problem is what git checkout does with an argument that could be two different things. Git resolves reference names before raw object IDs. If a branch exists whose name is the same 40-hex string as the pinned commit, git checks out the branch.
So the attacker creates a branch literally named 9f2c1a... — the full approved hash — points it at malicious code, and makes it the default branch. The agent asks for the reviewed commit, git hands it the attacker's branch, the agent reports the approved version, and the malicious code executes.
Variant 2: A Default Branch Named FETCH_HEAD
Gemini CLI uses a different install path and needed a different trick. It fetches the pinned commit, then checks out FETCH_HEAD.
Air found that a repository whose default branch is named FETCH_HEAD wins that resolution too. The checkout lands on the attacker's branch, and the correctly fetched, legitimately pinned code is silently discarded.
The Missing Line
In both variants the fix is the same single assertion after checkout, comparing what you asked for against what you actually got:
A Pin Is a Request. Verification Is the Control.
This is the whole bug, and it generalizes well beyond AI agents. Asking a system for a specific artifact is not a security control. Confirming that you received that specific artifact is. Package managers learned this the hard way and answered with checksums and lockfile integrity hashes; TLS learned it and answered with certificate validation. Every one of those controls exists because the request and the response are two different things, and only the second one is what you actually run. Four independent engineering teams, building four competing products, all shipped the request without the confirmation — because nothing ever failed loudly. A checkout that lands on the wrong code returns exit code zero and a clean working tree. Correctness and security diverged silently, which is exactly the failure mode that survives code review.
What the Attacker Gets
Air's framing is the one that matters operationally: a plugin runs with the same access as the person using the agent. It is not sandboxed away from your work. It is your work.
That means, at minimum:
- Source code in every repository the agent can read.
- Environment variables, which is where most teams still keep tokens.
- Cloud credentials and SSH keys sitting in the developer's home directory.
- Connected systems — every MCP server, CI runner, database and internal API the agent is already wired into.
- Write access to the codebase, which turns one compromised developer into a supply chain incident of your own.
There are two realistic paths in. Publish a clean plugin, pass review, build an install base, then turn it malicious. Or take over an existing repository that has already been reviewed and approved — an abandoned project, a lapsed domain behind a maintainer's email, a stolen maintainer credential.
Where Each Agent Stands
| Agent | Status | Fixed In |
|---|---|---|
| Anthropic Claude Code | Patched | 2.1.179 (June 17, 2026) |
| OpenAI Codex | Patched | 0.146.0 (August 12, 2026) |
| GitHub Copilot | No fix shipped | — |
| Google Gemini CLI | Will not be patched | Deprecated; migrate to Antigravity |
Air reported the findings in May 2026 and coordinated with vendors through June 2026. Public disclosure came on September 18, roughly four months later. The researchers credited are Or Nevo, Dor Granat and Niv Hoffman. No exploitation in the wild had been observed at the time of publication.
Google's position is the awkward one. Gemini CLI is being retired, so the answer to the vulnerability is a product migration to Antigravity rather than a patch. That is a defensible business decision and a bad security outcome: every installation still running Gemini CLI stays exposed permanently, and deprecated tools linger in developer environments for years.
Where Your Plugins Come From Decides Your Exposure
One detail meaningfully changes the risk picture. GitHub rejects branch and tag names that look like full commit hashes, precisely because this ambiguity in git is known. If your agent installs plugins from GitHub-hosted repositories, variant 1 does not work there.
Bitbucket and self-hosted git servers do not enforce that restriction. Neither does a plain git daemon someone stood up internally. So the practical question for your organization is not "which agent do we use" but:
- Which marketplaces are our agents configured to trust?
- Do any of them resolve plugins from non-GitHub hosts?
- Can a developer add a custom or internal plugin source on their own?
If the answer to the last one is yes — and in most teams running coding agents it is — then the host-level protection you are relying on is a default that anyone can opt out of.
No Marketplace Can Enforce a Pin It Does Not Resolve
Air's sharpest observation is structural: the pin is resolved inside the agent, on the client, so no marketplace can guarantee it. You can build the most rigorous plugin review process in the industry, sign every approved commit, maintain an immaculate allowlist — and none of it binds, because the component that decides what code actually runs is the git invocation on the developer's laptop. That is the same lesson client-side validation taught web security twenty years ago, reappearing in an ecosystem that rebuilt its trust model from scratch in eighteen months. AI agent tooling is currently retaking the supply chain security curriculum at high speed, and it will keep arriving at the same answers the hard way: verify at the point of execution, or do not claim to have verified at all.
What To Do Now
1. Update the Two Agents That Have a Fix
Claude Code to 2.1.179 or later, Codex to 0.146.0 or later. Both fixes are months old, which means the exposure in most organizations is not the vendor's patch cadence but your own rollout. Check the installed version on every developer machine, not just yours.
2. Constrain Plugin Sources on the Two That Do Not
For GitHub Copilot, restrict plugin installation to GitHub-hosted sources, where branch names shaped like commit hashes are rejected at the platform level. For Gemini CLI, treat the migration to Antigravity as a security task with a deadline, not a roadmap item.
3. Turn Off Plugin Auto-Update Where You Cannot Vouch for the Source
Auto-update is what makes this zero-click. On unpatched agents pulling from hosts that allow hash-shaped branch names, auto-update converts a reviewed plugin into a standing remote execution path. Move to a manual update workflow until the source is trustworthy.
4. Inventory Which Plugins Are Actually Installed
Most teams cannot answer this question today. Enumerate the plugins, skills and extensions loaded by every coding agent in the organization, record the source host for each, and flag every one that resolves from anywhere other than a platform you trust to enforce refname restrictions.
5. Treat the Agent's Environment as a Credential Boundary
Assume a plugin can read everything the developer can. Move secrets out of shell environment variables and into a broker that requires an explicit request, scope cloud credentials on developer machines to the minimum, prefer short-lived tokens, and alert on credentials used from unexpected contexts. This is the same control that limits the API key theft described in Anthropic's September threat report.
6. Add Agent Tooling to Your Vulnerability Management Scope
Coding agents and their plugins are production software running with developer privileges, and right now most of them sit outside the asset inventory, outside patch SLAs and outside the CVE feeds your team monitors. Plugin4Shell shipped without a CVE. If your only detection mechanism is a CVE feed, you would not have seen this at all.
The uncomfortable part is not the bug. It is how ordinary the bug is. Four well-resourced teams independently built the same plugin installer, and all four skipped the same verification step, in tooling that runs with full developer privileges on millions of machines. This is not an exotic AI failure mode. It is textbook supply chain security, rebuilt from zero by an ecosystem moving too fast to read the previous decade's incident reports.
Frequently Asked Questions
FETCH_HEAD, so naming the repository's default branch FETCH_HEAD achieves the same substitution. In both cases the correct pinned code is fetched and then discarded.My Take
I have written about one line in a repository running attacker code inside seven AI coding agents and about a swarm of agents breaching 395 organizations. Plugin4Shell belongs to the same family, and the family is getting predictable: the model is never the vulnerability. The plumbing around the model is.
What makes this one worth your attention is the shape of the mistake. Nobody misunderstood cryptography here. Everybody understood that a commit hash is immutable and that pinning to one is the correct control. They just never checked that the control engaged. The padlock was closed. It simply was not holding anything.
The industry response tells you where agent tooling sits on the maturity curve. Two vendors patched within weeks of disclosure, quietly, months ago. One has shipped nothing. One decided the vulnerability is a migration prompt. That spread — in a single class of product, from a single piece of research — is what an ecosystem looks like before security expectations have settled.
Meanwhile the install base keeps growing. The prior research Air cites reached 26,000 agents from one proof-of-concept plugin, and the SkillJacking study counted 925 hijacked skills across 134,000 agents. Those are not distribution numbers you can treat casually. Every plugin marketplace serving coding agents is a supply chain, and most of them are younger than the average unpatched vulnerability.
The practical takeaway is small and boring, which is usually the sign it is the right one: find out what version your agents are running, and find out where their plugins come from. Most teams cannot answer either question today.
So — do you know which plugins your coding agent loaded this morning, and which host they came from?
Related Articles:
- One Line in a Repository Runs Attacker Code Inside Seven AI Coding Agents
- OpenAI Published Six Misalignment Reports. Two of Them Describe Agents Building Their Own Channel.
- Russian State Hackers Used Claude Agents to Rewrite Their Malware Every Time It Got Caught
- One Attacker, Hundreds of AI Agents: How a Swarm Breached 395 Organizations Through PaperCut
- Frontier AI Agents Built Their Own Attack Chains. Nobody Told Them To.
- MCP Hits 97 Million Installations: The AI Infrastructure Moment Nobody Saw Coming