Case · DiggingBeagle record

Plugin4Shell let pinned AI-agent plugins resolve to different attacker-controlled code

AIR Security demonstrated a plugin supply-chain RCE across Claude Code, OpenAI Codex, GitHub Copilot and Gemini CLI. The agents requested reviewed, SHA-pinned plugin revisions but failed to verify that the working tree actually resolved to the pinned commit. Claude Code and Codex were patched; important host-specific limits apply, and no in-the-wild exploitation is established.

Scope

Reproducible vulnerability research against AI coding-agent plugin installation and update paths. The primary disclosure provides working proof of concept against four agents. It is not evidence that Plugin4Shell has been exploited against production victims.

Assessment profile

Assessment method
Setting
research demonstration
Exploitation
demonstrated
Evidence
Grade B
Remediation
patch available
Basis and provenance

The research PoCs and resolved-HEAD patch document pin/checkout confusion. Patches exist for named clients but host constraints and other vendor responses remain version-specific; no victim campaign is established. Assessment is a desk review of the retained canonical Claims and cited Source metadata at their recorded cutoff, not a new external verification. Impact remains ungraded.

Assessed Sep 24, 2026 using diggingbeagle.assessment/1.

At a glance

Mechanism and trust boundary

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

  1. 2026-06 (month precision)
    discovery

    AIR reports Plugin4Shell to affected vendors

    AIR says the four agent vendors were notified before public disclosure.

  2. Jun 16, 2026
    mitigation

    Claude Code 2.1.179 contains the reported fix

    AIR identifies 2.1.179 as the fixed Claude Code release.

  3. Jul 22, 2026
    mitigation

    OpenAI merges Codex checkout-verification fix

    PR #34644 documents the SHA/ref ambiguity and adds a resolved-HEAD equality check.

  4. Jul 29, 2026
    mitigation

    Codex 0.146.0 carries the fix

    AIR identifies Codex 0.146.0 as the fixed release.

  5. Sep 17, 2026
    Event type unspecified

    AIR publicly discloses Plugin4Shell

    The disclosure publishes the four-agent PoC, host-specific limitations and vendor status.

Claims & evidence

CLM-PLUGIN4SHELL-PATCHESAIR 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.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-ROOT-CAUSEThe 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.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-SHA-BRANCHFor 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.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-ZERO-CLICKAIR 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.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-FOUR-AGENTSAIR Security reported working Plugin4Shell proof-of-concept attacks against Claude Code, OpenAI Codex, GitHub Copilot and Gemini CLI.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-GITHUB-LIMITThe 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.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-NO-WILD-EXPLOITThe cited public material establishes reproducible proof of concept but does not establish exploitation of Plugin4Shell in the wild.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-UNPATCHED-STATUSAt 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.supported

Basis: reported finding

Link to claim
CLM-PLUGIN4SHELL-GEMINI-FETCH-HEADGemini 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.supported

Basis: reported finding

Link to claim

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 and 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.

Unknowns and contradictions

  • 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.

Sources and citation

Material revision history

  1. Sep 19, 2026 · Published version · first publication · revision 18
  2. Sep 25, 2026 · Published version · material revision · revision 38Public fields changed: assessment_profile