The industry locked AI coding-agent plugins to 40-character Git commit hashes and called that integrity. In September 2026, AIR Security showed the pin was mostly a checkout request. The same string can name a branch. Nothing compared HEAD to the reviewed object. Four major agents shared the gap.
What "pinned" was supposed to mean
Plugin marketplaces for Claude Code, OpenAI Codex, GitHub Copilot, and Gemini CLI advertise a familiar chain: review the plugin, pin a vetted commit SHA, install that object, auto-update only when the pin moves. The model looks like package pinning. Security teams treat a 40-hex lockfile entry as a hard guarantee that the working tree matches the reviewed code.
That guarantee never lived where people thought it lived. AIR's Plugin4Shell disclosure (17 September 2026) is blunt: each of the four agents checks out the pinned revision and then trusts whatever lands on disk. There is no post-checkout assertion that git rev-parse HEAD equals the pin. The cryptographic hash is still sound. The client never asked whether it received that hash.
One string, two meanings
Git resolves ref names before raw object IDs when both can match the same text. An attacker who controls a plugin repository can create a branch whose name is exactly the pinned 40-hex string, point that branch at malicious code, and set it as the default. A vulnerable install path that does the moral equivalent of git checkout <pin> can materialize the branch tip while the marketplace still displays the "correct" SHA.
That is verification theater. The config still shows the reviewed hash. The agent still believes it honored the pin. The tree can be different code. Gemini CLI's path is a cousin of the same failure: a default branch named FETCH_HEAD can win over the commit the agent just fetched, again because nothing checks the landed object.
Zero-click is the update path
Install-time risk is bad enough. Auto-update makes it worse. Claude Code and Codex default to background refresh: when a marketplace bumps a pin, the agent reclones and swaps the tree without a fresh human decision. AIR's chain is publish clean, gain trust, ship a still-clean bump that re-pins, then stage the SHA-named branch so the next auto-update lands attacker code. No new "install this plugin?" prompt. The user already trusted the name.
This sits on top of AIR's earlier work: malicious skills that went viral across tens of thousands of agents, and SkillJacking-style repo takeovers that hijacked hundreds of in-use skills. Plugin4Shell is the third act. Planting code is no longer required to break the pin. Confusing the client's notion of identity is enough.
Who actually closed the door
As of late September 2026 reporting:
- Claude Code fixed in 2.1.179+ (AIR).
- OpenAI Codex fixed in 0.146.0+, with explicit post-checkout verification.
- GitHub Copilot had no equivalent client-side fix at disclosure in the reporting we tracked.
- Gemini CLI was already being retired toward Antigravity CLI; coverage frames it as deprecated without a Plugin4Shell-specific fix ship.
Here is the uncomfortable inventory point from follow-on analysis: for many public catalogs the practical shield was never the agent. It was the Git host. GitHub and GitLab refuse branch and tag names that look like 40-character object IDs. Bitbucket and many self-hosted forges do not. Anthropic and Copilot docs still tell enterprises that any git host works for marketplaces. If security approved plugins because "everything is SHA-pinned," a large share of residual risk lived in which forge sat behind the URL, not in the lockfile line.
Host naming policy is not a patch. It does not own the FETCH_HEAD variant. It moves when the marketplace mirror moves. Treating GitHub's accidental hygiene as your integrity model is how you sleep through the next internal Bitbucket catalog.
What this week forces into the open
Agent plugins are not decorative skills. They touch source trees, shells, env vars, cloud credentials, MCP servers, and deploy hooks. An integrity failure at install time is arbitrary code execution inside the agent's permission boundary. The industry answered that risk with a phrase from package management: pin the commit. Plugin4Shell shows the phrase outran the code.
The corrective mental model is short enough to put on a sticky note: "SHA pinned" is not "SHA verified." Pins are requests. Verification is a comparison after the tree exists. Until every coding agent that installs from git does that comparison, marketplace badges and lockfile aesthetics remain aspirational. Until Copilot and remaining Gemini CLI surfaces catch up, the patch matrix is uneven on purpose, not by accident.
If you run these agents this week: upgrade Claude Code past 2.1.179 and Codex past 0.146.0; treat unpatched clients as exposed; inventory every marketplace URL by git host, not only by agent brand; disable background plugin auto-update where you cannot verify; and add the one-line HEAD check to any internal tool that does pinned checkouts. The missing assertion is boring. That is why four labs missed it the same way.

