Skip to main content
[← back to blog]

AI supply chain attacks now go after the tools that hold your keys

In March a poisoned LiteLLM release crashed the machine that caught it. Over 2026, attackers also hit an agent framework, a skill registry, a CI triage bot, an extension marketplace and LiteLLM again, because AI tools hold a developer's keys and update themselves.

Oct 31, 20267 min read

For about eleven hours on 29 October, Cursor's extension marketplace served a version of Anthropic's Claude Code extension that Anthropic never built. Cursor's security notice says the tampered versions were available between "about 2:27am PT and 1:35pm PT". Microsoft's analysis found a loader that tried to give the attacker a persistent way back in over SSH.

Cursor removed it and, in its words, "followed with a full shut down of the marketplace out of an abundance of caution", then rotated its keys and rebuilt. Cursor says errors in the malicious code made the backdoor step fail unless Cursor ran with administrator privileges. Anthropic told Microsoft its systems were not compromised. Neither Cursor's notice nor Microsoft's analysis says how the extension got in.

It landed eight days after LiteLLM shipped a poisoned release for the second time this year. Through 2025 and 2026, supply-chain attackers moved toward the AI toolchain: the packages, extensions, skills and CI bots that AI tools depend on. Those components run with a developer's keys, and they update themselves.

Container cranes at the Port of Oakland, California
Container cranes at the Port of Oakland, California (2025) Photo: Cullen328, CC BY-SA 4.0, dithered by Quint.

The AI supply chain attack that hit LiteLLM twice

LiteLLM, a Python library that gives AI software one interface to many model providers, is downloaded about 23 million times a week, according to Datadog. At 10:52 UTC on 24 March 2026, version 1.82.8 appeared on PyPI with no matching release on GitHub. An engineer at FutureSearch met it soon after, when an MCP plugin running inside Cursor pulled it in as a transitive dependency.

A file it planted ran at every Python start-up and launched another Python process, which ran it again, until the machine fell over. FutureSearch's disclosure, by Callum McMahon, is frank about the luck: "The fork bomb is actually a bug in the malware."

The payload was built to steal environment variables, SSH keys, cloud credentials, Kubernetes tokens and database passwords, LiteLLM's advisory says.

The March 2026 attack, disclosed
  1. FutureSearchMar 24, 2026
    Disclosure
    litellm 1.82.8 Supply Chain Attack on PyPI (March 2026)

    “The release contains a malicious .pth file that executes automatically on every Python process startup when litellm is installed.”

    Read the source
  2. LiteLLMMar 24, 2026
    Advisory
    Security Update: Suspected Supply Chain Incident

    “The compromised PyPI packages were litellm==1.82.7 and litellm==1.82.8. Those packages were live on March 24, 2026 from 10:39 UTC for about 40 minutes before being quarantined by PyPI.”

    Read the source
  3. Aqua SecurityApr 1, 2026
    Analysis
    Update: Ongoing Investigation and Continued Remediation

    “On March 19, 2026, a threat actor used compromised credentials to publish malicious releases of Trivy version 0.69.4, as well as trivy-action and setup-trivy.”

    Read the source

PyPI quarantined 1.82.8 and the earlier 1.82.7 at 11:25 UTC, 46 minutes after the first upload by FutureSearch's count (LiteLLM says about 40). In that window they were downloaded 46,996 times, and 2,054 of the 2,337 PyPI packages that depend on LiteLLM had version ranges that accepted them.

Who would have pulled it
2,054 of 2,337PyPI packages that depend on LiteLLM had version ranges that accepted the poisoned releases
accepted thempinned outside the rangeFutureSearch, March 24, 2026

The way in was a security scanner. On 19 March an attacker with stolen credentials published a malicious Trivy release and repointed 76 of 77 tags of its GitHub Action; pipelines that trusted the tags still printed a normal scan, Aqua found. LiteLLM's town hall write-up names three factors: one shared CI environment, static publishing credentials in environment variables, and an unpinned Trivy. Its summary: "a compromised package in CI had access to secrets it should not have had, and those secrets were then used in the release path."

How a scanner in CI became a poisoned LiteLLM release
  1. 01
    Scanner
    A malicious Trivy release goes out on 19 March.
  2. 02flagged
    CI
    LiteLLM's unpinned scan runs it beside static publishing secrets.
  3. 03flagged
    Publish
    Stolen PyPI credentials upload 1.82.7 and 1.82.8 on 24 March.
  4. 04flagged
    Install
    Unpinned installs and agent tooling pull them in.
  5. 05
    Crash
    A bug in the payload takes down a FutureSearch machine.
  6. 06
    Quarantine
    PyPI pulls both versions 46 minutes after the first.

LiteLLM handled it in the open, with hashes for every release back to v1.78.0, Mandiant on the forensics and a rebuilt pipeline. Users of its official Docker image were not affected in March, because that path pinned its dependencies.

On 21 October it happened again. A malicious litellm 1.107.0 was on PyPI from 11:39 to 13:23 UTC, and the official Docker tags, latest included, were bad from 11:46 to 14:20 UTC (LiteLLM). This payload also wanted "LLM provider API keys, and sessions for Claude, Codex, Gemini, Cursor, Copilot and other AI coding tools," Datadog found.

This time the door was an agent platform. A configuration file pushed to a public LiteLLM repository in May held an administrative key to an internal LiteLLM Agent Platform deployment; on 10 October the attacker used it to take over that deployment, then extracted the GitHub CLI token of the organization's owner (attack chain).

The controls added after March did not stop it. The release went out "with seemingly legitimate build provenance that faithfully recorded the malicious fork as the source," Datadog found. LiteLLM's security team wrote on 30 October that trusted publishing and signing "prove that an artifact came from our pipeline", and that "no pipeline controls can defend against an attacker who is an organization owner, because the owner owns the pipeline."

The shape was visible in 2025

In August 2025 an attacker stole an npm token from the Nx build system through a workflow injection in its GitHub Actions (advisory). The malicious versions, Nx's post-mortem says, "scanned user systems for sensitive data, attempted to use local AI tools (like Claude and Gemini), and uploaded the results to a public GitHub repo via the GitHub CLI." They were live for four hours, caught because they "lacked NPM provenance signing."

That set the pattern for 2026: a stolen publishing credential, then a release under the real name that strips the installing machine of its keys.

Four more attacks on the AI toolchain in 2026

In early February, Koi Security examined 2,857 skills on ClawHub, the registry for the OpenClaw agent, and found 341 malicious ones in a campaign it named ClawHavoc, The Hacker News reported; 335 used fake prerequisites to walk users into installing the Atomic Stealer infostealer.

Cline, the open-source coding agent, had added an AI issue-triage workflow on 21 December 2025. Any GitHub user could trigger it, it could run shell commands, and it shared a cache with the nightly release workflow, so instructions planted in an issue title could reach Cline's publishing secrets, Cline's post-mortem explains.

Adnan Khan reported it privately on 1 January; it sat until he published it as Clinejection on 9 February. Cline pulled the workflows within 30 minutes but revoked the wrong npm token, and on 17 February someone used the survivor to publish cline@2.3.0, which installed OpenClaw on every machine that took it (advisory).

Giving an LLM shell access in a CI context where it processes untrusted input is functionally equivalent to giving every GitHub user shell access.

Cline post-mortem, February 2026

In June the Miasma worm went after the agents directly. On 5 June a compromised contributor account pushed a commit to Microsoft's Azure/durabletask repository that "planted configuration files that execute a credential-harvesting payload when a developer opens the repository in Claude Code, Gemini CLI, Cursor, or VS Code," StepSecurity found. Hours later GitHub's automated abuse detection disabled 73 Microsoft repositories in 105 seconds.

Eleven days later the target was an agent framework. Between 6:12 and 6:37 PM Pacific on 16 June, a token tied to a Mastra maintainer published 116 malicious packages, by Mastra's count. Each added a dependency on a typosquat of the dayjs library whose install hook fetched a second stage.

Microsoft attributes it with high confidence to Sapphire Sleet, a North Korean state actor. The maintainer had been phished through a compromised LinkedIn account; Mastra required MFA on npm "but we also allowed (mistakenly) token bypass."

Why AI tools are worth attacking

The stealers above went looking for the same things: environment variables, SSH keys, cloud credentials, publishing tokens and, by October, model-provider keys and AI coding sessions. AI tools sit on that pile: a model gateway holds keys for every provider it routes to, and a coding agent runs in a shell with the developer's cloud profile.

They also update themselves. LiteLLM's March advisory warned it could arrive as an unpinned dependency "through AI agent frameworks, MCP servers, or LLM orchestration tools", which is how it reached FutureSearch. One Mastra user reported that their dependency-update bot pulled the poisoned versions within minutes.

The newer problem is that these tools act on what they read. Miasma's files were instructions addressed to agents, and Clinejection's way in was an issue title read by a model with a shell. The supply chain now includes prose.

What the developer did, and what ran with their rights
What the developer did
  • Ran an MCP plugin inside an editor
  • Opened a repository in an AI coding tool
  • Ran npm install on an agent framework
  • Let a bot triage public issues
What the code could reach
  • Every variable in the environment
  • SSH keys and cloud credentials
  • Model-provider keys and AI tool sessions
  • Release secrets in CI

How long they stayed up

LiteLLM's March release was exposed by its own bug. Nx and Mastra were caught by missing provenance and unexpected publishing patterns. The windows were short and still long enough: 46 minutes became 46,996 downloads.

How long each one stayed up
  1. 46 min
    litellm 1.82.7 and 1.82.8 on PyPI, 24 March 2026
    found because the malware crashed a machine
  2. ~2 h
    litellm 1.107.0 on PyPI, 21 October 2026
    Docker tags stayed bad until 14:20 UTC
  3. 4 h
    Nx on npm, 26 August 2025
    flagged by missing provenance
  4. ~5 h 45 min
    Mastra on npm, 16 June 2026
    first malicious publish to the last one unpublished or deprecated
  5. ~8 h
    cline@2.3.0 on npm, 17 February 2026
    published with a token that survived rotation
  6. ~11 h
    Claude Code extension on Cursor's marketplace, 29 October 2026
    the marketplace was then shut down and rebuilt

Shrinking what a poisoned release can reach

  • Pin, lock and wait. Install from lockfiles, pin CI actions to full commit SHAs, and let new releases sit a few days before automation adopts them.
  • Alert on releases with nothing behind them. A version with no matching tag, no CI run or a new publisher is what caught Nx and Mastra.
  • Decide what an install can reach. Run installs and builds where neither developer nor release secrets live, and disable install scripts where the build allows.
  • Give each tool its own narrow credential. A model gateway needs model keys; a triage bot needs no shell and no release secrets. When you rotate, test the old credential.
  • Review agent config like CI config. Files under .claude/, .cursor/, .gemini/ and .vscode/ in a pull request or a fresh clone can run code when the folder opens. The MCP security checklist covers the MCP side.
  • Watch what a new tool does in its first hour. A fresh package that reads ~/.ssh or cloud credentials, starts a process that outlives it, or calls a host nobody has seen is telling you what its registry page will not.

Three of these payloads ran inside an AI tool's own session: an MCP plugin in Cursor, an agent opening a repository, an editor extension. Quint runs on developer machines and observes every agent's file, process and network activity at the OS level, with no changes to the agent. It scores the sequence on the device in real time: a fresh dependency that reads cloud credentials and then opens a socket to an unknown host is the kind of sequence it flags, however clean the package looks. To see one scored on a real session, book a demo.

Then pick the AI tool in your stack with the broadest credentials and write down what its next update could reach if that update were hostile.

Related reading

Your agents are running. See what they're actually doing.

Book a demo