Your Coding Agent Pinned the Commit. It Never Checked Where It Landed

September 21, 2026
11 min read

September 21, 2026
11 min read
There is a particular kind of security finding that is worth more than its severity score, because the mechanism teaches you something you can apply elsewhere. This is one of those.
Details come from reporting on AIR's disclosure by The Register, Help Net Security and Cyber Security News. Patch status and vendor positions are as reported at disclosure and may have moved since; section 7 says what I am not claiming. The reading of the mechanism, and everything from section 4 onward, is mine.
On 17 September 2026, researchers at AIR published Plugin4Shell: a zero-click remote code execution flaw in the plugin systems of four major AI coding agents. They found it in May 2026, built working proof-of-concept exploits against all four, and disclosed to the vendors in June.
Status as reported at publication:
| Agent | Status |
|---|---|
| Claude Code | Patched in 2.1.179 |
| Codex | Patched in 0.146.0 |
| Copilot | Reported unpatched |
| Gemini CLI | Deprecated; no fix planned, users directed elsewhere |
Four independent teams, four separate codebases, and the same mistake in all of them.
That last part is the tell. When four competitors ship the same bug, it is not four lapses of attention. It is a shared assumption nobody wrote down.
Plugin marketplaces pin a plugin to a specific commit hash after review. This is the control everybody trusts — pin to a SHA and you get exactly the bytes someone looked at. It is the same instinct behind a lockfile.
Here is what the affected agents actually did:
So far so good. This part works.
Also fine, in isolation.
Nothing stops you naming a branch a94a8fe5ccb19ba61c4c0873d391e987982fbbd3. It is just a string.
Because it never looked. As the researchers put it: the agent checks out the exact commit the marketplace pinned, but never verifies it landed there.
The Gemini CLI variant is a different route to the same place — a branch named FETCH_HEAD redirecting the checkout away from the fetched commit — which is the detail that makes this a class of bug rather than one vendor's slip.
The generalisable lesson
A pin is not integrity. A pin is a request for integrity. The integrity comes from the verification step afterwards — the one that asks "did I actually get what I asked for?" — and that step is the one that gets skipped, because in the overwhelming majority of runs the answer is yes and the check looks like dead code. Every place in your own system where you fetch something by identifier and then use it without re-deriving that identifier from what arrived has this shape.
A supply-chain bug normally needs a user to do something: install, upgrade, approve a prompt. Plugin4Shell needed none of that, and the reason is a feature everybody likes.
Claude Code and Codex run background auto-updates by default. When a marketplace bumps a pinned SHA, the agent re-runs the checkout on its own schedule. If the attacker has already staged the malicious branch, the swap happens silently, with no prompt, no install and nobody present.
Which reverses the usual advice:
For ordinary dependencies, "turn on automatic updates" is good security guidance, because most of what auto-update delivers is patches. For an execution surface where the update path itself is the vulnerable component, automatic updating is the delivery mechanism. The two cases look identical on a policy page and behave in opposite directions.
It is tempting to read "plugin vulnerability" as a contained problem. It is not, and this is the part that should decide how seriously a small team takes it.
Code executed through a coding agent's plugin system gets, in the researchers' framing, the same reach into a company's systems and data as the employee running the agent. On a normal developer machine, that means:
Source, including private repositories. Read access to everything checked out locally, and write access to anything the developer can push to.
Live cloud sessions. Whatever is already authenticated in the terminal — cloud CLI credentials, kubeconfig, database tunnels. No credential theft required; the session is open.
Environment files and secret stores. The .env files, the local keychain entries, the tokens sitting in a shell profile because rotating them was a chore.
The agent's own tool surface. Every integration the agent is already permitted to call, now driven by somebody else's code with the user's approval history behind it.
A developer workstation is the least segmented machine in most companies and holds the most reach. That is fine when the code running on it is code a human chose. It is a different proposition when an update path can change what runs without anyone deciding to change it.
Here is the structural point, and the reason I think this matters beyond one patch cycle.
Your application dependencies are governed. There is a lockfile, a scanner, a review step when someone adds a package, and an SBOM if you sell to anyone who asks for one. That machinery took the industry twenty years to build and it mostly works.
Your agent's plugins, skills, extensions and marketplace installs have none of it.
Application dependencies usually run inside a service with a scoped identity. Agent plugins run on a workstation with a human's full authority. The layer with less review has more reach, which is precisely backwards, and it happened by accident: plugins arrived as a productivity feature, not as a software supply chain, so nobody attached the supply-chain machinery to them.
Most teams I talk to cannot answer "which agent plugins are installed across the team, at what versions, from which publishers" without going desk to desk. That is not negligence. Nobody ever told them it was a question.
Four things, roughly an afternoon, and none of them require a security team.
Claude Code 2.1.179 and Codex 0.146.0 or later. For anything reported unpatched or deprecated, the decision is whether it keeps a plugin surface at all — an unfixed update path is not something you monitor, it is something you turn off.
Every agent plugin, skill and extension installed across the team, with publisher and version. It is usually a short list and the exercise is over in an hour. If it turns out to be a long list, that is the finding.
Auto-update the agent binary — that is how you receive fixes like these. Consider gating plugin updates behind a human, at least for plugins that can execute code. These are two different decisions and most teams currently make one of them by default for both.
Short-lived cloud credentials, no long-lived production tokens in shell profiles, and no database tunnel that stays open all day. This is the control that holds regardless of which agent ships the next bug, which is what makes it worth doing first.
And one thing to add to your own code, whatever you are building:
Find every place you fetch by identifier — a commit, a digest, a model version, a document id — and check whether anything re-derives that identifier from what actually arrived. If the answer is "we asked for it, so it must be it", you have the Plugin4Shell shape in your own system. It costs a few lines to close and it is invisible until the day it is not.
No confirmed real-world exploitation has been reported. This is a disclosure with working proof-of-concept exploits, not an incident report. Figures circulating about how many agents a malicious plugin could reach are scenario modelling, not counts of compromised installs, and I have deliberately left them out.
Patch status was a moving target at disclosure and sources differ. Claude Code and Codex are consistently reported as fixed at the versions above. Reporting on Copilot's exposure is not consistent — some accounts describe it as unpatched, others as mitigated by platform controls. Check your own vendor's advisory rather than this table.
This is not a Git vulnerability. Git resolving an ambiguous reference in a documented order is Git working as specified. The bug is in the agents assuming the result matched the request. Blaming the tool would be the wrong lesson and would lead you to fix nothing.
I have not reproduced any of it. Everything in section 2 is my reading of published descriptions of the mechanism, not independent verification.
The interesting thing here is not that four coding agents had a bug. It is which assumption they all shared: that naming a thing precisely is the same as checking you received it.
That assumption is everywhere. It is in every integration that trusts a webhook because it carries the right id, every cache that returns by key without validating the payload, every pipeline that pulls latest and calls it reproducible. Pinning to a hash felt safe because a hash is specific — but specificity is not verification, and the gap between them is exactly where this class of bug lives.
Meanwhile the practical exposure is unglamorous and immediate: a code path that can change what executes on a developer's machine without anyone approving the change, on the least segmented machine in the building.
Update the agents today. Then spend an hour finding out which plugins your team has installed, because right now that is a question most teams cannot answer — and it is the same question your first serious customer security review is going to ask.
Sources: The Register, "AI coding agents' 0-click RCE flaw could hand attackers keys to the kingdom", 17 September 2026 — the disclosure timeline, the two attack routes and the vendor positions. Help Net Security, "Zero-click RCE vulnerability hit four major AI coding agents", 18 September 2026 — the May 2026 discovery, the June disclosure, the patched versions 2.1.179 and 0.146.0, and the framing of the privileges the executed code inherits. Cyber Security News — the 40-character branch-name mechanism and the FETCH_HEAD variant affecting Gemini CLI. The research is AIR's. The generalisation in section 2, the auto-update argument in section 3, the inventory argument in section 5 and every recommendation are mine. For the previous supply-chain incident on this beat see the RubyGems package flood, and for the permission model that limits what a compromised plugin can reach see agent permission systems.
IdeaToMVP Academy
4-week live cohort for founders. Learn to ship AI agents, scope MVPs, and automate your business — taught by the same team that writes these guides.