Back to Intelligence

Plugin4Shell Supply-Chain Flaw in Claude Code, Codex, and Copilot: Detection and Remediation Guide

SA
Security Arsenal Team
September 20, 2026
14 min read

Air Security disclosed a supply-chain vulnerability class this week that should be on every CISO's radar — especially organizations whose developers run AI coding agents with plugin or extension ecosystems. Dubbed Plugin4Shell, the flaw affects four widely used AI coding agents and allows a plugin repository owner to swap the code an agent installs even after that plugin was pinned to a specific, previously reviewed version. In practical terms: your team reviewed the plugin, approved the commit hash or version tag, and locked it — and the repo owner can still silently replace what gets executed on the developer's workstation.

Per Air Security's disclosure, Anthropic has patched the issue in Claude Code 2.1.179, and OpenAI has patched it in Codex 0.146.0. GitHub Copilot's remediation status is incomplete in the public reporting, and the fourth affected agent has not been fully detailed in the initial coverage — treat any agent with a plugin/extension model as potentially exposed until vendors confirm otherwise.

This is not a theoretical risk. Developer workstations hold source code, cloud credentials, SSH keys, CI/CD tokens, and signing material. A malicious plugin executed through a trusted AI agent inherits the developer's privileges and, often, the agent's own tool-execution permissions — which increasingly include the ability to run shell commands without per-command approval. The supply-chain lesson of the last few years applies here in full: pinning is only a control if the pinning mechanism actually binds the code.

Technical Analysis

Affected Products

ProductStatusFixed Version
Anthropic Claude CodePatched2.1.179
OpenAI CodexPatched0.146.0
GitHub CopilotPatch status unconfirmed at time of writingMonitor vendor advisories
Fourth agent (undisclosed in initial reporting)UnknownMonitor Air Security's disclosure

No CVE identifier has been published in the reporting available at the time of this writing. Track Air Security's write-up and vendor security advisories for a formal assignment.

How the Attack Works (Defender's View)

The flaw sits in the plugin resolution and pinning logic of the affected agents. The intended trust model is:

  1. Developer selects a plugin from a registry or repository.
  2. Developer (or security team) reviews the code at a specific version/commit.
  3. The agent "pins" the plugin to that reviewed version, so future upstream changes are not silently pulled.
  4. On install or update, the agent fetches the pinned code and executes it.

Plugin4Shell breaks step 4. The entity controlling the plugin's code repository can cause the agent to retrieve and execute different code than what was pinned — for example by manipulating what the repository serves for a given reference, or by exploiting how the agent resolves the pinned identifier back to repository content. The integrity check, if any, binds to an identifier the attacker can influence rather than to the reviewed content itself.

The exploitation requirements are favorable to the attacker:

  • No victim-side mistake is required beyond having installed (or auto-updated) a plugin whose repository is attacker-controlled or later compromised.
  • The attack executes in the context of the AI agent process, which on most developer machines means full user privileges and, critically, an agent that is already authorized to execute shell commands and modify files.
  • Delivery is silent: it rides the normal plugin install/update path, so nothing anomalous appears in the developer's workflow.

Attack Chain Observable Indicators

From a SOC perspective, the chain produces a recognizable telemetry signature:

  1. Agent CLI process (Node.js/Python-based for most of these tools) initiates outbound HTTPS to code-hosting infrastructure (e.g., GitHub, plugin registries, raw content CDNs).
  2. Agent process writes new or modified files to its plugin/extension directory in the user profile.
  3. Agent process — or a freshly written plugin artifact — spawns a shell (cmd.exe, powershell.exe, bash, sh) or an interpreter to execute plugin logic.
  4. Optional second stage: the plugin payload performs discovery, credential access (~/.aws, ~/.ssh, browser stores, .env files), or egress to non-registry infrastructure.

Exploitation Status

At the time of writing, Air Security's disclosure is a coordinated vulnerability disclosure, not a report of confirmed in-the-wild exploitation. There is no CISA KEV entry associated with this issue yet. However, the barrier to weaponization post-disclosure is low: the technique is now public, the affected user base (developers at enterprises running AI-assisted coding at scale) is high-value, and the pre-patch installed base is large. Treat this as patch-now, hunt-now.

Detection & Response

The detections below target the core behavioral signature: AI coding agent processes fetching, writing, and executing plugin code. Tune the process names to the agents actually deployed in your environment — inventory first, then hunt.

Sigma Rules

YAML
---
title: AI Coding Agent Spawning Shell or Interpreter Child Process
id: 9c4e7a21-3b58-4f6a-b2d1-8a7c5e9f0134
status: experimental
description: Detects AI coding agent CLI processes (Claude Code, Codex, Copilot CLI) spawning shells or script interpreters, consistent with plugin code execution as described in the Plugin4Shell disclosure. Baseline agent behavior in your environment before enabling at high level.
references:
  - https://thehackernews.com/2026/09/plugin4shell-lets-repository-owners.html
  - https://attack.mitre.org/techniques/T1059/
  - https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/09/18
tags:
  - attack.execution
  - attack.t1059
  - attack.supply_chain_compromise
  - attack.t1195.002
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\claude.exe'
      - '\codex.exe'
      - '\copilot.exe'
      - '\node.exe'
      - '\python.exe'
  selection_parent_cli:
    ParentCommandLine|contains:
      - 'claude'
      - 'codex'
      - 'copilot'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\curl.exe'
      - '\certutil.exe'
  condition: selection_parent and selection_parent_cli and selection_child
falsepositives:
  - Legitimate agent tool execution approved by the developer (expected behavior for coding agents — baseline and tune by parent path)
  - Build and test commands run through the agent
level: medium
---
title: File Write to AI Agent Plugin Directory
id: 2d8f6b47-91a3-4c5e-8b0d-6f3a2c1e9075
status: experimental
description: Detects creation or modification of executable content in AI coding agent plugin/extension directories, which could indicate a swapped or newly installed plugin as described in Plugin4Shell.
references:
  - https://thehackernews.com/2026/09/plugin4shell-lets-repository-owners.html
  - https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/09/18
tags:
  - attack.persistence
  - attack.supply_chain_compromise
  - attack.t1195.002
logsource:
  category: file_event
  product: windows
detection:
  selection_path:
    TargetFilename|contains:
      - '\.claude\plugins\'
      - '\.claude\extensions\'
      - '\.codex\plugins\'
      - '\.codex\extensions\'
      - '\.copilot\plugins\'
      - '\.github\copilot\extensions\'
  selection_ext:
    TargetFilename|endswith:
      - '.js'
      - '.mjs'
      - '.py'
      - '.ps1'
      - '.sh'
      - '.bat'
      - '.exe'
      - '.dll'
  condition: selection_path and selection_ext
falsepositives:
  - Normal plugin installation and updates by the agent
  - Developer authoring local plugins
level: medium
---
title: Linux AI Coding Agent Spawning Shell After Plugin Fetch
id: 5b1c9e82-4d7a-4f23-9a56-2e8d0b3c7146
status: experimental
description: Detects node/python-based AI coding agents on Linux/macOS spawning interactive shells or download utilities, consistent with malicious plugin execution following a repository fetch.
references:
  - https://thehackernews.com/2026/09/plugin4shell-lets-repository-owners.html
  - https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/09/18
tags:
  - attack.execution
  - attack.t1059.004
  - attack.supply_chain_compromise
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/node'
      - '/python'
      - '/python3'
      - '/claude'
      - '/codex'
  selection_child:
    Image|endswith:
      - '/bash'
      - '/sh'
      - '/zsh'
      - '/curl'
      - '/wget'
      - '/nc'
      - '/ncat'
  selection_suspicious_cli:
    CommandLine|contains:
      - 'base64 -d'
      - '| sh'
      - '| bash'
      - 'curl '
      - 'wget '
      - '/tmp/'
      - '/dev/tcp/'
  condition: selection_parent and selection_child and selection_suspicious_cli
falsepositives:
  - Legitimate agent-driven build, install, and test workflows — tune to your developer baseline
level: high

KQL — Microsoft Sentinel / Defender

This hunt identifies AI coding agent processes that fetched content from code-hosting infrastructure and subsequently spawned a shell or interpreter within a 30-minute window — the behavioral sequence Plugin4Shell would produce. It assumes Defender for Endpoint device data; adapt process names to your inventory.

KQL — Microsoft Sentinel / Defender
let Lookback = 7d;
let AgentProcesses = dynamic(["claude.exe", "codex.exe", "copilot.exe", "node.exe", "python.exe"]);
let ShellProcesses = dynamic(["cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe", "wscript.exe", "cscript.exe", "curl.exe", "certutil.exe", "bash", "sh"]);
let AgentNetwork =
    DeviceNetworkEvents
    | where TimeGenerated > ago(Lookback)
    | where InitiatingProcessFileName in~ (AgentProcesses)
    | where RemoteUrl has_any ("github.com", "raw.githubusercontent.com", "objects.githubusercontent.com", "registry.npmjs.org", "pypi.org")
       or RemoteUrl endswith ".git"
    | project NetworkTime=TimeGenerated, DeviceName, DeviceId, InitiatingProcessFileName, InitiatingProcessId, RemoteUrl;
let AgentShellSpawn =
    DeviceProcessEvents
    | where TimeGenerated > ago(Lookback)
    | where InitiatingProcessFileName in~ (AgentProcesses)
    | where InitiatingProcessCommandLine has_any ("claude", "codex", "copilot", "node", "python")
    | where FileName in~ (ShellProcesses)
    | project SpawnTime=TimeGenerated, DeviceName, DeviceId, InitiatingProcessFileName, InitiatingProcessId, SpawnedProcess=FileName, ProcessCommandLine, AccountName;
AgentShellSpawn
| join kind=inner AgentNetwork on DeviceId, InitiatingProcessId
| where SpawnTime between (NetworkTime .. NetworkTime + 30m)
| extend HoursSinceEvent = datetime_diff("hour", now(), SpawnTime)
| project SpawnTime, DeviceName, AccountName, InitiatingProcessFileName, SpawnedProcess, ProcessCommandLine, RemoteUrl
| order by SpawnTime desc;

A second, simpler hunt for plugin-directory writes, useful as a standing analytic rule once tuned:

KQL — Microsoft Sentinel / Defender
let Lookback = 7d;
let PluginPaths = dynamic(["\\.claude\\", "\\.codex\\", "\\.copilot\\", "\\plugins\\", "\\extensions\\"]);
DeviceFileEvents
| where TimeGenerated > ago(Lookback)
| where FolderPath has_any (PluginPaths)
| where FileName endswith ".js" or FileName endswith ".py" or FileName endswith ".ps1"
   or FileName endswith ".sh" or FileName endswith ".exe" or FileName endswith ".dll"
| where ActionType in ("FileCreated", "FileModified")
| summarize FileOps = count(), Files = make_set(FileName, 20), LastWrite = max(TimeGenerated)
    by DeviceName, FolderPath, InitiatingProcessFileName, InitiatingProcessAccountName
| order by LastWrite desc;

Velociraptor VQL

This artifact enumerates AI agent plugin directories on Windows endpoints and correlates recently written executable artifacts with the owning processes — useful for scoping which machines had plugin code land after the disclosure date.

VQL — Velociraptor
-- Plugin4Shell scoping hunt: enumerate executable artifacts in AI agent plugin directories
-- and list currently running agent processes with their command lines.
LET plugin_globs = SELECT glob, FullPath, Mtime, Size
FROM glob(globs=[
  'C:/Users/*/.claude/plugins/**/*.{js,mjs,py,ps1,sh,bat,exe,dll}',
  'C:/Users/*/.claude/extensions/**/*.{js,mjs,py,ps1,sh,bat,exe,dll}',
  'C:/Users/*/.codex/plugins/**/*.{js,mjs,py,ps1,sh,bat,exe,dll}',
  'C:/Users/*/.codex/extensions/**/*.{js,mjs,py,ps1,sh,bat,exe,dll}',
  'C:/Users/*/.copilot/**/*.{js,mjs,py,ps1,sh,bat,exe,dll}',
  'C:/Users/*/.github/copilot/**/*.{js,mjs,py,ps1,sh,bat,exe,dll}'
])

LET agent_procs = SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)claude|codex|copilot|node|python'
  AND CommandLine =~ '(?i)claude|codex|copilot'

SELECT * FROM plugin_globs
WHERE Mtime > '2026-09-01'
UNION ALL
SELECT NULL AS glob, Exe AS FullPath, CreateTime AS Mtime, NULL AS Size
FROM agent_procs

Run this across your developer fleet. Any executable artifact in a plugin directory modified after the public disclosure date on a machine running an unpatched agent version warrants review of the artifact's hash against the plugin's official release, plus a check of the machine's egress traffic for the same window.

Remediation & Verification Script

The following Bash script inventories installed AI coding agents on macOS/Linux developer workstations, flags versions below the patched releases, and lists recently modified plugin directory contents for triage. Deploy via your MDM or run during incident scoping.

Bash / Shell
#!/usr/bin/env bash
# Plugin4Shell verification script - Security Arsenal
# Checks Claude Code and Codex versions against patched releases and inventories plugin dirs.
set -u

CLAUDE_FIXED="2.1.179"
CODEX_FIXED="0.146.0"

ver_lt() {
  # returns 0 if $1 < $2 (semver-ish comparison)
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" != "$2" ]
}

echo "=== AI Coding Agent Version Check ==="

if command -v claude >/dev/null 2>&1; then
  cv=$(claude --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
  if [ -n "$cv" ]; then
    if ver_lt "$cv" "$CLAUDE_FIXED"; then
      echo "[VULNERABLE] Claude Code $cv installed - upgrade to >= $CLAUDE_FIXED"
    else
      echo "[OK] Claude Code $cv (>= $CLAUDE_FIXED)"
    fi
  else
    echo "[WARN] Claude Code present but version unreadable - verify manually"
  fi
else
  echo "[INFO] Claude Code CLI not found in PATH"
fi

if command -v codex >/dev/null 2>&1; then
  xv=$(codex --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
  if [ -n "$xv" ]; then
    if ver_lt "$xv" "$CODEX_FIXED"; then
      echo "[VULNERABLE] OpenAI Codex $xv installed - upgrade to >= $CODEX_FIXED"
    else
      echo "[OK] Codex $xv (>= $CODEX_FIXED)"
    fi
  else
    echo "[WARN] Codex present but version unreadable - verify manually"
  fi
else
  echo "[INFO] Codex CLI not found in PATH"
fi

echo ""
echo "=== Plugin Directory Inventory (modified since 2026-09-01) ==="
for d in "$HOME/.claude/plugins" "$HOME/.claude/extensions" \
         "$HOME/.codex/plugins" "$HOME/.codex/extensions" \
         "$HOME/.copilot" "$HOME/.config/github-copilot"; do
  if [ -d "$d" ]; then
    echo "--- $d ---"
    find "$d" -type f \( -name '*.js' -o -name '*.mjs' -o -name '*.py' \
      -o -name '*.sh' -o -name '*.ps1' -o -name '*.exe' -o -name '*.dll' \) \
      -newermt '2026-09-01' -exec ls -la {} \; 2>/dev/null
  fi
done

echo ""
echo "=== Upgrade commands (run as appropriate for your install method) ==="
echo "# Claude Code:  npm update -g @anthropic-ai/claude-code   (or your package manager)"
echo "# Codex:        npm update -g @openai/codex               (or your package manager)"

For Windows fleets, use Intune/Configuration Manager to push version inventory via the equivalent PowerShell (Get-Command claude, codex and version parsing) and the same directory-recency logic against %USERPROFILE%\.claude and %USERPROFILE%\.codex.

Remediation

1. Patch immediately.

  • Anthropic Claude Code: upgrade to 2.1.179 or later. For npm-installed deployments: npm update -g @anthropic-ai/claude-code. Enforce the minimum version through your MDM/software management platform — developer self-updates are not a control.
  • OpenAI Codex: upgrade to 0.146.0 or later.
  • GitHub Copilot: the patch status was not confirmed in the initial reporting. Monitor GitHub's security advisories and changelog, and apply compensating controls (below) until a fixed release is confirmed.
  • Fourth agent: track Air Security's disclosure for the identity of the remaining affected product and its remediation.

2. Inventory and audit your plugin footprint — today.

You cannot defend plugins you don't know exist. Enumerate every plugin/extension installed across developer workstations (the script above gets you started). For each one, answer: who owns the repository, is it actively maintained, was it reviewed, and does the installed artifact's hash match the official release for the pinned version? Unowned, abandoned, or single-maintainer plugins from personal accounts are your highest-risk entries — this is exactly the trust relationship Plugin4Shell abuses.

3. Compensating controls while patching is in flight.

  • Disable or restrict plugin auto-install/auto-update in agent configuration where supported; require explicit, reviewed installation.
  • Where agents support allowlists, restrict plugins to an internally vetted set and mirror them into an internal repository you control. A plugin served from your own artifact store cannot be swapped by an upstream repo owner.
  • Apply egress filtering on developer segments: agents need code-hosting and registry domains; they do not need arbitrary internet egress from the workstation. A swapped plugin that cannot call home loses most of its value.
  • Reduce agent autonomy where feasible: require per-command approval for shell execution until your fleet is patched. This is a friction trade-off, but it converts silent execution into a visible event.

4. Hunt retroactively.

The vulnerable window is not just "going forward." Any plugin install or update that occurred before patching could have delivered swapped code. Run the KQL and VQL hunts above across at least the trailing 90 days of retained telemetry, prioritizing machines running agent versions below the fixed releases. Any executable artifact in a plugin directory whose hash does not match the official pinned release is a DFIR ticket, not a cleanup task.

5. Update your third-party and AI tooling risk processes.

AI coding agents are now firmly in the same supply-chain category as package managers and IDE extensions. Add them to your software inventory, your SBOM scope, and your vendor risk review. If your incident response plan does not yet include "developer workstation agent compromise" as a scenario, add it — the credential density on these machines (cloud tokens, SSH keys, CI/CD secrets) makes them tier-one targets.

6. Credential hygiene for the blast radius.

If retroactive hunting surfaces any suspicious plugin artifact on a workstation, treat all credentials reachable from that machine as exposed: rotate cloud access keys, revoke CI/CD tokens, and re-issue SSH keys. Do not assume the agent sandbox (where one exists) contained execution — Plugin4Shell operates precisely in the gap between what the user approved and what the agent ran.

The Bottom Line

Plugin4Shell is a reminder that version pinning is only as strong as the binding between the pin and the bytes that actually execute. Four major AI coding agents got that binding wrong, and the fix is trivially available for two of them. Patch Claude Code and Codex now, inventory your plugin estate, hunt the pre-patch window, and put AI agent tooling under the same supply-chain governance you apply everywhere else. The attackers watching this disclosure are doing the math on unpatched fleets — make sure yours isn't part of it.

Related Resources

Security Arsenal Healthcare Cybersecurity AlertMonitor Platform Book a SOC Assessment healthcare Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.