Pinning a dependency to a commit hash is one of the oldest supply-chain safeguards there is. It means: install exactly this code, and nothing else. On 18 September, Air Security showed that in four major AI coding agents, that promise could be broken.

What happened

The research, named Plugin4Shell, targets how coding agents verify plugin versions. Agents lock plugins to a specific commit hash. But Git can interpret a requested commit SHA as a branch name. A repository owner can create a branch whose name matches the pinned hash and point it at different code. The agent then installs the swapped code while still reporting the locked version.

  • Affected: Claude Code, OpenAI Codex, GitHub Copilot and Google Gemini CLI.
  • Fixed: Claude Code 2.1.179 and Codex 0.146.0.
  • Not fixed at the time of reporting: Copilot. Gemini CLI will not be fixed, according to the report, because it is being retired.
  • Limitation: GitHub does not allow branch or tag names that look like commit hashes, so plugins hosted on GitHub were protected. The attack works on other hosts such as Bitbucket and private git servers.
  • Status as of 18 September: no CVE assigned and no evidence of exploitation in the wild.

A swapped plugin runs with the user's access. In practice that means the developer's files, credentials and logins.

The lesson: the safeguard lived inside the thing being attacked

Pinning is a good control. The problem is where it was enforced: inside each agent, implemented four different ways, patched on four different timelines. If your developers use more than one agent, and most teams do, your supply-chain protection is only as strong as the slowest vendor to patch.

That is not a criticism of any single vendor. It is an argument for having one policy that does not depend on any of them.

What a policy layer outside the agent gives you

DarkControl sits between the AI agent and the operating system. It checks the shell commands, file writes and network calls an agent makes against a central policy and returns a verdict: allow, ask or deny. Anything that doesn't match a rule defaults to ask.

  • One rule, every agent: the same policy applies whether the command comes from Claude Code, Codex, Copilot or Cursor.
  • Ask or deny for fetching code from non-allowlisted git hosts, so a plugin coming from an unfamiliar Bitbucket workspace or private server needs a human decision first.
  • Deny reads of credential files and outbound connections to unknown destinations, which limits what a swapped plugin can do even if it does install.
  • Every attempt is recorded in an immutable audit log, so when research like this lands you can answer a simple question: did any of our agents fetch plugins from non-GitHub hosts in the last month?

Source: The Hacker News, 'Plugin4Shell lets repository owners…', 18 September 2026: https://thehackernews.com/2026/09/plugin4shell-lets-repository-owners.html


Want to see what your agents actually install? Run DarkControl's free 7-day watch-only audit on up to 10 devices. Nothing is blocked and no credit card is needed.

Book a demo