Reconstruction
Plugin marketplaces try to solve a familiar supply-chain problem by pinning an approved plugin to an immutable Git commit. That guarantee sounds cryptographic: review commit X, record its SHA, and later installs should execute commit X even if the repository changes.
Plugin4Shell breaks the promise one layer lower. AIR found that four coding agents asked Git to check out the pinned identity but did not verify the commit actually materialized in the working tree. For Claude Code, Codex and GitHub Copilot, an attacker controlling the upstream repository could use a default branch whose name exactly matched the 40-character SHA on hosts that allow that naming pattern. Git resolves the ambiguous name as a ref, the command succeeds, and the agent can install attacker-controlled branch content while the marketplace still appears pinned to the reviewed commit.
Gemini CLI reached the same integrity failure through a different path. It fetched the desired object and then checked out FETCH_HEAD; a default branch with that name could redirect resolution. The shared bug is therefore not that Git is broken. The client treated command success as proof of artifact identity.
The attack becomes zero-click where installed plugins update in the background. A benign plugin can pass review, become trusted, and later materialize different code after the upstream repository is changed or hijacked. That code executes with the permissions of the developer running the coding agent. Unlike the earlier Codex malicious-repository CVEs, the user does not have to open an obviously attacker-controlled project: the compromised object is an extension the ecosystem already reviewed and pinned.
Mechanism & boundary
- 01
Publish or inherit control of a legitimate plugin repository
The attacker either owns a plugin that passes marketplace review or later gains control of the repository behind an already trusted plugin.
Boundary: publisher identity / trusted marketplace entry
- 02
Marketplace pins a reviewed Git commit
The catalog records an immutable-looking SHA intended to bind future installs and updates to reviewed code.
Boundary: reviewed artifact / mutable upstream repository
- 03
Exploit ambiguous Git name resolution
On affected paths, attacker-controlled ref names can win resolution even though the client requested the pinned identity.
Boundary: requested commit identity / materialized working tree
- 04
Client fails to verify resolved HEAD
The Git command returns success and the agent accepts the checkout without proving that HEAD equals the reviewed commit.
Boundary: command success / artifact-integrity proof
- 05
Background update installs the substituted plugin
Where plugin updates run automatically, the attacker-controlled working tree can reach an already-installed agent without a new user click.
Boundary: trusted extension update / local code execution
- 06
Plugin code inherits developer authority
The malicious extension can execute with whatever filesystem, credential, repository and tool access the coding-agent process possesses.
Boundary: plugin ecosystem / developer workstation authority
Timeline
- 2026-06
AIR reports Plugin4Shell to affected vendors
discoveryAIR says the four agent vendors were notified before public disclosure.
- Jun 16, 2026
Claude Code 2.1.179 contains the reported fix
mitigationAIR identifies 2.1.179 as the fixed Claude Code release.
- Jul 22, 2026
OpenAI merges Codex checkout-verification fix
mitigationPR #34644 documents the SHA/ref ambiguity and adds a resolved-HEAD equality check.
- Jul 29, 2026
Codex 0.146.0 carries the fix
mitigationAIR identifies Codex 0.146.0 as the fixed release.
- Sep 17, 2026
AIR publicly discloses Plugin4Shell
reportThe disclosure publishes the four-agent PoC, host-specific limitations and vendor status.
Claims & evidence
reported findingsupported
AIR reports Claude Code fixed in 2.1.179 and Codex fixed in 0.146.0; OpenAI's public Codex change verifies resolved HEAD after checkout and rejects a mismatch.
reported findingsupported
The common integrity failure is that the client requests a pinned commit but does not verify that the final checked-out HEAD equals the commit identity the marketplace approved.
reported findingsupported
For Claude Code, Codex and GitHub Copilot, AIR demonstrated a variant where a default branch named exactly like the pinned 40-hex commit can win Git name resolution on hosts that permit such branch names.
reported findingsupported
AIR describes the attack as zero-click for already-installed plugins where background auto-update re-runs the vulnerable checkout path, including default update behavior reported for Claude Code and Codex.
reported findingsupported
AIR Security reported working Plugin4Shell proof-of-concept attacks against Claude Code, OpenAI Codex, GitHub Copilot and Gemini CLI.
reported findingsupported
The SHA-shaped-branch variant is not exploitable through default GitHub-hosted repositories because GitHub rejects branch or tag names that resemble commit SHAs; AIR says other supported hosts such as Bitbucket or self-hosted Git can still permit the condition.
reported findingsupported
The cited public material establishes reproducible proof of concept but does not establish exploitation of Plugin4Shell in the wild.
reported findingsupported
At public disclosure, The Register reported no GitHub Copilot client fix and said Google would not patch the deprecated Gemini CLI; GitHub argued its host-side SHA-like branch restriction prevents the reported branch-name attack for GitHub-hosted repositories.
reported findingsupported
Gemini CLI had a separate variant: it fetched the pinned commit but then checked out FETCH_HEAD without verifying the resolved object, allowing a default branch named FETCH_HEAD to redirect the working tree.
Implications
Plugin4Shell shows that a security property can be correct in the marketplace database and false on the developer's machine. The reviewed SHA was not enough because the client never verified the materialized object. Agent extension ecosystems therefore need end-to-end artifact identity: publisher, repository, version, checkout result and runtime permissions all belong to the same trust decision. For security auditors using coding agents, this is especially important because a compromised extension sits below the model and can tamper with the very environment being used to review code.
Controls & mitigations
- Update Claude Code to 2.1.179 or later and Codex to 0.146.0 or later.
- After every plugin checkout, resolve the actual HEAD commit and compare it byte-for-byte with the approved pinned SHA; abort on mismatch.
- Prefer artifact stores or Git hosts that prevent ambiguous ref names, while treating host-side restrictions as defense in depth rather than a replacement for client verification.
- Disable or tightly control automatic plugin updates when the client cannot prove artifact identity.
- Treat plugin repository ownership changes, deleted or reclaimed namespaces and marketplace repinning as supply-chain security events.
- Run agent extensions with least privilege because a plugin compromise inherits the coding agent's filesystem, credential and repository access.
What remains unknown
- No cited source establishes exploitation in the wild.
- The practical exploitability of the SHA-shaped branch variant depends on the Git host's branch-name policy and marketplace configuration.
- The cited public material does not establish how many installed agents were actually exposed to attacker-controlled repositories.
- GitHub's host-side mitigation covers GitHub-hosted repositories for the SHA-shaped branch variant, but it is not the same control as client-side resolved-commit verification.