AIDEFEND in Action AIA-0102 Validated Research Published: Oct 23, 2026

Plugin4Shell: Git Reference Shadowing Defeats Reviewed Plugin Pins

Air Security demonstrated that AI coding clients could install different plugin code from the commit reviewed by a marketplace. An attacker controlling an already trusted plugin repository could shadow a pinned SHA with a default branch of the same name, or shadow FETCH_HEAD in Gemini CLI. Background updates then loaded malicious code without a fresh install decision. The defect is verification of the resolved working-tree commit, not a failure to review the marketplace entry; both repository control and a compatible client/hosting path are material prerequisites.

Supply Chain CompromiseClient SecurityAI Coding Agent
7 applicable AIDEFEND defenses

Threat Analysis

SHA pinning is supposed to bind a reviewed plugin to one immutable Git commit. The researchers found clients that requested the pin but did not check the commit actually installed. For the background-update scenario, a benign plugin is already installed, the marketplace approves a new benign commit, and the attacker controls the plugin repository. A separate repository takeover can supply that control, but the takeover figures from other Air research are not Plugin4Shell victim counts.

Claude Code, Codex and GitHub Copilot were tested with a default branch whose 40-hex name equals the approved SHA. On compatible Git hosts, cloning creates that local branch and checkout resolves the name as a ref. The commit can remain benign while the branch tip contains malicious code. A non-default branch does not create the same local resolution behavior. GitHub's rejection of 40-hex branch names limits this variant; it does not establish that every supported host is safe.

Gemini CLI used a different route: fetch the correct pinned object, then checkout FETCH_HEAD. A default branch named FETCH_HEAD could win that lookup. The graph keeps the variants as alternatives. Comparing the resulting HEAD commit to the approved SHA before executing anything closes the specific resolution defect; verifying only the requested ref or successful Git exit status does not.

The public vulnerability identifier CVE-2026-86063 applies to the Claude Code pinning flaw, with versions below 2.1.179 affected and 2.1.179 patched. OpenAI's 0.146.0 release also records Git-plugin SHA verification. The research's September 17 statements about GitHub Copilot and Gemini CLI are dated status, not a verified October 23 assurance about all releases. Initial plugin adoption remains required even when a later background update needs no additional click. The report provides controlled demonstrations, not a confirmed malicious campaign against every installed client.

Applicable AIDEFEND Defenses (7)

AID-H-003.010
Deployed AI Software Vulnerability Remediation Lifecycle
Very High
Inventory the actual client and plugin-loader versions, update affected Claude Code to 2.1.179 or later and Codex to a supported release containing the 0.146.0 fix, then verify the running binaries and a controlled SHA-shadow negative test. The Claude advisory applies below 2.1.179; do not apply its CVE or version bounds to other clients. Where no verified fix is available, disable this plugin/update path through managed enforcement instead of trusting a review badge.
AID-H-030.005
Admission Decision Orchestration & Triggered Revalidation
High
Install plugins only through an enterprise install broker that serves exact, reviewed artifact bytes. The broker holds a digest-bound allow decision per plugin version, installs that snapshot into the client's plugin directory and returns a receipt whose installed digest is read back; the client never clones the publisher's repository itself, so a SHA-named default branch or a FETCH_HEAD branch upstream has nothing to shadow. Treat every marketplace re-pin as an admission trigger rather than a routine update: when the pinned SHA, the publisher status or the repository default branch changes, invalidate the previous decision, hold background updates for that plugin and re-run admission against the newly resolved commit and its actual tree before any client receives it. This requires pointing clients at the broker or an internal marketplace it feeds, and it covers only plugins installed that way.
AID-I-001.002
MicroVM & Low-Level Sandboxing
High
Confine the client and its complete plugin/hook child-process tree in a verified managed VM or supported OS sandbox without developer-home secrets, host agent sockets or unrestricted production mounts. This limits what substituted code can read and change after activation. A sandbox covering only model tool calls misses code executed by the plugin loader; verify that loader and background updater processes inherit the same outer boundary.
AID-H-028.006
Client Distribution, Plugin & Update Integrity Verification
Medium
Before any plugin import or hook runs, enumerate the complete client-loader population, copy exact package bytes into protected immutable staging, and validate publisher, version and content digest against an independently signed allowlist. Load the same verified bytes; a requested Git ref, success exit code or plugin-supplied inventory is insufficient. G003 requires a host-specific pre-activation adapter, so this is a controlled-client/vendor integration until each loader path is proven covered, including Gemini's separate checkout route.
AID-D-004.001
Static Artifact Integrity Re-verification & Drift Monitoring
Medium
Re-verify what is actually in the plugin directory against the approved pin. A file-integrity job that runs with its own read-only identity compares each installed plugin's HEAD commit and tree digest with the marketplace-approved SHA and a stored manifest of its files, and raises a finding on any mismatch, including the case where the requested ref and the resolved HEAD differ or where checkout FETCH_HEAD resolved to the attacker-named branch. Run it after every update and before the client's next start. This catches the substituted checkout in both variants, but it is detection after the files land; whether it beats activation depends on the update-to-start gap, so it supports rather than replaces the loader check.
AID-I-001.004
Sandbox Network Egress Restrictions
Medium
If substituted plugin code does run, limit where it can reach. Enforce default-deny egress outside the sandbox that holds the client, its updater and its hooks, allowing only the marketplace, the model endpoint and the repositories the task needs, and test raw IPs, redirects, proxies and DNS from inside that tree. This blocks callback and bulk exfiltration after activation; it does not stop local damage or reads of whatever the sandbox still exposes, and the research did not demonstrate a specific exfiltration destination, so the effect here is containment rather than a proven block.
AID-E-003.003
Confirmed Malicious Code & Persistence Eviction
Medium
When a shadowed plugin is confirmed, evict it from everywhere it can load, not just the machine that noticed. Enumerate every client that installed the affected plugin or version, preserve the substituted bytes for forensics, remove the plugin directory and its cached clone, deny the malicious commit and tree digests in the broker or marketplace so no updater can pull them back, then verify by digest that no runtime still holds them. Reinstall only from the reviewed snapshot. This is response after the fact and depends on the inventory the techniques above provide.

What Defenders Should Do Now

  • Inventory the exact client binaries, plugin loaders, marketplace sources and update processes actually used. Upgrade affected Claude Code and Codex to supported fixed builds, verify the running versions, and test both a SHA-shaped default branch and the product-specific FETCH_HEAD route in an isolated repository.
  • Until a loader's fix is verified, disable the affected plugin installation/update route through managed policy. Restricting hosts that accept SHA-shaped branches can reduce one variant, but does not address FETCH_HEAD shadowing.
  • For controlled clients, verify the resolved HEAD and an independently approved exact package digest before imports or hooks execute. Stage and load the same immutable bytes, cover every search path, and reject incomplete inventory or stale allowlists.
  • Stop clients from cloning publisher repositories at all: serve plugins from an enterprise install broker or internal marketplace that installs reviewed, digest-bound snapshots, and treat every marketplace re-pin or default-branch change as a trigger to re-run admission before any update ships.
  • Through MDM-managed client settings, limit marketplaces to approved sources hosted where SHA-shaped branch names are rejected and turn off background plugin auto-update, so a new pin applies only after a logged install action.
  • Run clients, background updaters and plugin hooks within a verified outer sandbox that excludes developer secrets and production authority. Keep the containment boundary outside the plugin's own configuration.
  • Run a read-only integrity check of installed plugin directories against the approved SHA and file manifest after every update. On a confirmed substitution, preserve the bytes, remove the plugin and its cached clone from every affected client, deny the malicious digests at the broker, and reinstall only from the reviewed snapshot.

Conclusion

AIDEFEND  maps Plugin4Shell to verified client remediation, broker-based plugin admission that re-validates on every re-pin, managed client policy over marketplaces and auto-update, pre-activation integrity checks, isolation and egress limits for plugin execution, and fleet eviction once a substitution is confirmed. The concrete lesson is to authorize the code that will actually run. A marketplace's reviewed SHA has defensive value only when the client verifies that the resolved checkout and loaded bytes are the approved ones.

Last updated: