AI Newsway

Plugin4Shell: A Zero-Click RCE Hits Claude Code, Codex, Copilot and Gemini CLI

Security firm Air says every major coding agent trusts a pinned plugin version it never verifies

|6 min read0
AI Summary
Air Security disclosed Plugin4Shell, a zero-click remote code execution flaw affecting Claude Code, OpenAI Codex, GitHub Copilot and Gemini CLI. All four agents check out a marketplace-pinned commit without verifying it landed in the working tree, letting an attacker who controls a plugin repository serve malicious code while the pin still appears honored. Anthropic patched Claude Code 2.1.179 and OpenAI patched Codex 0.146.0. Microsoft has shipped no fix, and Google will not patch the deprecated Gemini CLI.
Source code on a developer's screen β€” Plugin4Shell turns a routine git checkout inside AI coding agents into remote code execution.
Source code on a developer's screen β€” Plugin4Shell turns a routine git checkout inside AI coding agents into remote code execution.

Security firm Air disclosed a vulnerability on Thursday that gives an attacker remote code execution on the machines of developers using AI coding assistants, with no user interaction required. Named Plugin4Shell in the company's research report, it affects Anthropic's Claude Code, OpenAI's Codex, GitHub Copilot and Google's Gemini CLI.

Two of those four vendors have shipped a patch. Anthropic fixed it in Claude Code 2.1.179 and OpenAI in Codex 0.146.0, while Microsoft has released nothing for Copilot and Google says it will not patch the deprecated Gemini CLI at all.

Nothing in the attack touches a model or an agent's reasoning. It sits one layer down, in the marketplace plumbing that delivers add-ons onto a working laptop β€” and a plugin runs with whatever access the engineer operating the agent has.

Key takeaways

  • Air researchers Or Nevo, Dor Granat and Niv Hoffman found the same missing verification step in Claude Code, Codex, GitHub Copilot and Gemini CLI.
  • Anthropic shipped a fix in Claude Code 2.1.179 and OpenAI in Codex 0.146.0; Microsoft has released nothing for Copilot and Google will not patch the deprecated Gemini CLI.
  • Background plugin auto-update, on by default in Claude Code and Codex, is what removes the click from the attack.

Why SHA pinning was supposed to end this

Pinning exists because the alternative already failed publicly. Air's own prior work supplied much of the evidence: a deliberately malicious skill it published into a trusted marketplace reached more than 26,000 agents, and a follow-up study hijacked 925 skills that were already in active use, touching 134,000 agents. The industry response was to stop trusting names. A branch or a version tag can move; a 40-character commit hash cannot.

That reasoning is sound, and it is exactly the reasoning that failed here. Pinning only delivers its guarantee if somebody checks the outcome, and the client-side code doing the install turned out to check the request instead. Enterprises that went furthest β€” vetting plugin source, pinning a reviewed commit, treating the hash as an audit artifact β€” inherited the flaw most completely, because their entire control depended on the step that was skipped.

Where the check goes missing

Git is unusually permissive about what a branch may be called. Its own reference-format validator will accept a name made of 40 hexadecimal characters, and when a string is simultaneously a valid reference and a plausible object ID, git picks the reference and downgrades the conflict to a warning nobody reads. An attacker holding the plugin repository can therefore create a branch whose name is character-for-character the pinned hash, promote it to the repository default, and watch the install land on content of their choosing while the agent reports success at the expected commit. Claude Code, Codex and GitHub Copilot all fall to that variant.

Gemini CLI breaks along a different seam. It fetches the pinned object correctly and writes it to the repository's FETCH_HEAD file, then performs a checkout of FETCH_HEAD by name β€” a name a hostile repository is free to claim as its default branch, at which point the correctly fetched commit is simply discarded.

What closes both variants is a single assertion: after the checkout completes, resolve HEAD, compare it to the hash that was requested, and abort if they differ. The distinction that matters is checking the resolved result rather than the reference that was asked for, which is precisely what the Gemini variant slips past.

The auto-update multiplier

An install-time bug would be serious. This one is worse because agents re-run that same checkout on their own schedule. Claude Code and Codex refresh installed plugins in the background as default behavior, so a hash bump upstream propagates without an install step, a prompt or any visible event. The attacker never has to convince anyone to add anything; the plugin they need is already sitting on the target machine, already trusted.

Two entry paths follow from that, and neither requires compromising a marketplace. An attacker can publish something genuinely useful, clear review, and change its contents later. Or they can take over the repository behind a plugin written by somebody else β€” the precise scenario pinning was adopted to contain. Both halves have now been demonstrated separately, which is what makes the chain credible rather than theoretical.

Two vendors patched, two did not

Air notified all four vendors in June under coordinated disclosure, and the responses diverged sharply. Anthropic and OpenAI shipped fixes. Google declined, telling the researchers Gemini CLI is deprecated and steering users to its Antigravity environment, which has no marketplace plugin pinning to subvert. Microsoft, according to the researchers, never responded at all.

GitHub disputes its exposure. A spokesperson told The Register the platform blocks branch and tag names resembling commit hashes, so the technique cannot run there. Air's answer is that agents do not only consume GitHub-hosted marketplaces β€” Anthropic's documentation lists Bitbucket and self-hosted git among supported backends, and those accept hash-shaped branch names normally. With Microsoft citing roughly 90 percent Fortune 500 adoption of Copilot, the unpatched surface is not small.

What this means for plugin governance

The uncomfortable structural point is that no marketplace can fix this for its users. The pin is evaluated on the client, so the guarantee a marketplace advertises is enforced somewhere it has no code running. That inverts the assumption behind a lot of current enterprise procurement, where an approved marketplace is treated as the control boundary. Efforts like the vendor-neutral Agent Plugins standard may help by making verification behavior specifiable rather than per-vendor. For now the practical advice is narrow: update Claude Code and Codex, and for Copilot and Gemini CLI, inventory what is installed and where it is hosted. Anyone who followed the ChainDrop worm that poisoned 444 npm packages carrying valid signatures will recognize the pattern β€” the integrity mechanism was present, and presence was mistaken for enforcement.

FAQ

Is my AI coding agent affected by Plugin4Shell?

You are exposed if you run Claude Code, OpenAI Codex, GitHub Copilot or Gemini CLI with plugins installed from a marketplace. Claude Code 2.1.179 and Codex 0.146.0 contain fixes, so updating closes it for those two. Copilot and Gemini CLI currently have no patch available.

Does using GitHub-hosted plugins protect me?

Partly. GitHub rejects branch and tag names shaped like commit hashes, which blocks the primary variant on that platform. Air's researchers note that agents also support marketplaces on Bitbucket and self-hosted git servers where the trick still works, and that GitHub's rule does nothing about the separate Gemini CLI variant.

Can a marketplace fix this on its own?

No. The pinned commit is resolved on the client machine when the agent runs its checkout, so only an agent-side verification step can guarantee the pin was honored. A marketplace can restrict which git hosts it permits, but that narrows supported configurations without closing the underlying flaw.

How do you feel about this article?

SJ

Discussion

Sign in to post
Loading...

Related articles

ChainDrop Worm Poisoned 444 npm Packages β€” With Valid Signatures
Developer Tools

ChainDrop Worm Poisoned 444 npm Packages β€” With Valid Signatures

A self-propagating npm worm hit 444 packages in four hours, published through trusted workflows with valid provenance attestations.

Seung Jung33 days ago
A Poisoned Rust Crate Was Live for 86 Minutes. It Had 245 Million Downloads.
Developer Tools

A Poisoned Rust Crate Was Live for 86 Minutes. It Had 245 Million Downloads.

Malicious releases of arrayref, internment and append-only-vec pulled an infostealer through a typosquatted proc-macro1 dependency during compilation.

Seung Jung26 days ago
Slack's New Channel Type Can Only Be Created by a Coding Agent
Developer Tools

Slack's New Channel Type Can Only Be Created by a Coding Agent

Slack Code launches with Claude, Devin, GitHub Copilot and Vercel. Agents open the channels, humans review or stop them, and archives serve as audit logs.

Seung Jung28 days ago
Researchers Found 227 Install Commands Pointing at Code Nobody Owns
Developer Tools

Researchers Found 227 Install Commands Pointing at Code Nobody Owns

A scan of 6,214 domains found 120 llms.txt files pointing coding agents at unregistered packages, and one slot already held live malware.

Seung Jung21 days ago
AI Agents Flooded RubyGems With 2,000 Packages. Sign-Ups Closed for Four Days
Developer Tools

AI Agents Flooded RubyGems With 2,000 Packages. Sign-Ups Closed for Four Days

A forensic report reconstructs the May GemStuffer campaign, in which AI agents pushed 2,000+ gems and forced RubyGems to freeze new sign-ups for four days.

Seung Jung6 days ago
GitHub's HydraFusion Stops Picking a Model. It Builds a Workflow Instead.
Developer Tools

GitHub's HydraFusion Stops Picking a Model. It Builds a Workflow Instead.

GitHub's Project HydraFusion assembles a multi-model plan for every Copilot coding request, trading single-model simplicity for sharply lower cost.

Seung Jung5 days ago