Supply-chain attacks on AI and LLM tooling, and how to defend

Poisoned packages, images and CI actions hit AI tooling in 2026. The shared pattern, the dated facts and the checks to run on your own app project.

Timothy Lindblom

Founder, Newly

Published Last updated

Supply-chain attacks on AI tooling follow one pattern: an attacker gets control of how a package or image is published, and the poisoned release runs wherever you install it, next to your keys. To defend, pin exact versions with hashes or digests, delay brand-new releases, keep publishing tokens short-lived, and treat any package an AI tool suggests as unknown until you have looked it up.

What is the pattern behind these attacks?

Each incident below travelled through a path the victims already trusted: a maintainer's token, a release workflow, a moving tag, or a package name that a model made up. Dates come from the primary sources.

Dated supply-chain incidents affecting AI and developer tooling
IncidentDateWhat was poisonedHow it ranSource
Trivy GitHub ActionMarch 19 to 20, 202676 of 77 trivy-action version tags, all setup-trivy tagsInside CI jobs that referenced a tagGHSA-69fq-xp46-6x23
LiteLLM and Telnyx on PyPIMarch 2026Malicious releases after an API token exposure traced to an exploited Trivy dependencyAt install. LiteLLM was live 2 hours 32 minutes, 119,000+ downloadsPyPI blog
ChainDropAugust 4, 2026400+ npm packages from unrelated publishersA preinstall script that took npm, GitHub and AWS credentials and spreadMicrosoft
LiteLLM 1.107.0October 21, 2026PyPI wheels, Docker Hub and GHCR tagsAt every Python start, even if litellm was never importedLiteLLM, Datadog
react-codeshiftJanuary 14, 2026A package name a model invented, referenced by 237 repositoriesWhen an agent ran the install command in a skill fileAikido
postmark-mcpSeptember 25, 2025An npm MCP server, from 1.0.16 onwardAdded a hidden BCC to every email the agent sentSnyk

Datadog states that no connection between the two LiteLLM incidents has been established. OWASP lists the class as LLM03:2025 Supply Chain.

Five stages of a supply-chain attack on AI tooling, each with the control that interrupts itPublishingidentity takenShort-livedpublish tokensPoisoned releaseor tag publishedCooldown, exactpins, digestsYour install, buildor CI run pulls itLockfile withhashes, npm ciCode runs atinstall or startScripts off,least privilegeKeys on thathost leaveInventory, thenrotate elsewhereTop row: how the attack travels. Bottom row: the control that interrupts that stage.
A left-to-right flow of five stages with a defence under each one.

What happened with LiteLLM on October 21, 2026?

LiteLLM is an open-source gateway that many teams put in front of their model providers. Everything below is the maintainer's own account, last updated October 21 at 20:30 UTC and marked "incident contained, investigation in progress" at our check on October 24, 2026.

  • Cause: three developers' GitHub CLI credentials were abused, branch protection was overridden, and a release workflow was pointed at a lookalike repository, Berri-AI/litellm instead of BerriAI/litellm.
  • PyPI: litellm==1.107.0 was live from 11:39:51 to 13:23 UTC.
  • Docker Hub: the tags v1.107.0, latest, main-latest and main-stable resolved to the bad image from 11:46:56 to 14:20 UTC. GHCR tags were affected until 13:51 UTC.
  • Scope: version 1.107.0 only. Earlier versions and the private Enterprise release were reported as unaffected.
  • Open question: how the attackers first got in is not confirmed. The maintainer says a coding tool's GitHub token appeared in logs of an exposed internal deployment, and it does not call that the proven entry point.

Reading these facts

These are vendor-claimed findings. Datadog's separate write-up describes the same startup files and a similar release window. The maintainer also says an embargoed enterprise release fixes a separate vulnerability, with disclosure scheduled for October 27, 2026. Recheck the report before you act on a detail.

Why does AI tooling raise the stakes?

A model gateway or agent host holds many keys in one place. Datadog lists what the LiteLLM malware went after: cloud credentials, SSH and Git tokens, LLM API keys and coding assistant sessions. The maintainer's rotation list includes every provider key stored in the proxy database, its master and virtual keys, and the database password.

  • Code runs without being imported. The LiteLLM files run when Python starts, so a package you installed and never used still ran. Flags that turn off install scripts do not help here.
  • Skill files act like instructions. Aikido found agents running the install command a generated skill file contained, and the package behind the name did not exist.
  • Local tools run with your rights. The MCP security guidance says a local MCP server can run any command the client can, and that clients should show the exact command before starting one.

Where can this reach my own app project?

If you download your project code or connect your own repository, these files are yours to read. Look in five places.

  1. App dependencies: package.json and the lockfile. Look for ranges such as ^ with no committed lockfile.
  2. CI workflows: lines in .github/workflows that say uses: owner/action@v1. A tag can be moved, as the Trivy advisory shows. Red's page on fake security-audit workflows covers a related GitHub Actions campaign.
  3. Server code and images: requirements.txt, and Dockerfile FROM lines ending in :latest.
  4. Agent tooling: the MCP server list in your coding tool and any skill file that runs npx or pip.
  5. Keys within reach: every .env file and CI secret. In Expo, a variable that starts with EXPO_PUBLIC_ is written into the app bundle, so an AI provider key never belongs there. AI inside your app uses credits, which a leaked key can spend for a stranger.

Related: the 15-minute app check, the chatbot self-test and the security hub.

What defends each place?

Controls, what they stop and what they leave open
ControlWhat to look forWhat it stopsWhat it leaves open
Exact pins with hashes--require-hashes in pip. In npm, npm ci in CI, which fails when the lock and manifest disagreeA floating range quietly pulling a new bad releaseA bad version you pinned yourself
Release cooldownnpm min-release-age, in days. Default is unsetShort windows. PyPI suggests about three days, and 1.107.0 was live about two hours on PyPIA bad release that stays unnoticed for longer than the delay
Install scripts offnpm 12 makes dependency scripts opt-in. On older npm, ignore-scripts defaults to falseInstall-time droppers such as ChainDrop's preinstall stepCode that runs at Python start or at import
Actions pinned to a commit SHAA 40-character hash after @, as GitHub recommends, and a read-only default tokenA moved tag, as in the Trivy caseA bad commit you chose, and secrets given to the job
Images by digestimage@sha256:..., since tags can be reassigned and digests cannotA repointed latestA digest taken after the image was already bad
Short-lived publishingIf you publish packages, Trusted Publishing with tokens that expire after 15 minutesA stolen release token that works until someone noticesA taken-over CI workflow that publishes in that window
Reviewed agent toolsExact start command, pinned version, and for HTTP servers a token audience checkSurprise installs and hidden behaviour such as the BCCA later update that changes behaviour after your review

What do I do if a bad version ran on my machine?

Order matters, because a key typed on an infected machine leaks again. This follows the LiteLLM report and Datadog's advice; other incidents have their own vendor lists.

  1. Find out. Run pip show litellm and compare image digests with the report. Finding the named files confirms exposure. Not finding them leaves the question unknown.
  2. Stop Python from starting on that host until the startup files are removed, remove them, and end the background process the report names.
  3. Rebuild the environment or container from scratch and pin version 1.106.2 or another release you have checked.
  4. From a different machine, rotate the host's cloud role, every provider key, the gateway keys and the database password. Red's rotation guide has the general order.
  5. Read your cloud and provider logs for use of those keys from places you do not recognise, starting from the install time.

For the wider October picture, including Railway, Zeabur and TiDB Cloud, see Red's October 2026 security tracker and the ChainDrop check.

Where do you stand?

Mark each item. Everything starts as unknown, because an unchecked item is unknown. Move one to confirmed only when you hold the evidence listed under it.

Your supply-chain check

  • Detected: You found the problem.
  • Unknown: Not checked yet, or the check could not tell.
  • Confirmed by owner evidence: You checked and kept the proof.
  1. 1. Every Python and JavaScript dependency is pinned to an exact version with a lockfile or hashes, and installs in CI fail when the lock does not match.

    Evidence: the lockfile in your repository, plus the CI log line showing npm ci or pip install --require-hashes.

  2. 2. No machine, image or CI cache ever ran litellm 1.107.0, or the cleanup and rotation were done after it did.

    Evidence: pip show litellm output and the image digest from each place Python runs.

  3. 3. Every third-party GitHub Action is pinned to a full commit SHA, and the default token permission is read-only.

    Evidence: your .github/workflows files and the repository's Actions permission setting.

  4. 4. Docker images are pulled by digest, not by latest or another moving tag.

    Evidence: the FROM lines in your Dockerfiles and your deployment config.

  5. 5. Each MCP server and agent skill is listed, version-pinned, and its start command has been read by a person.

    Evidence: the list of servers and skills with the command each one runs and who publishes it.

  6. 6. AI provider keys live on a server and not in the app bundle, and you can rotate each one in under an hour.

    Evidence: an inventory of every key with its owner, where it is stored and the date of its last rotation.

0 detected6 unknown0 confirmed by owner evidence

Your answers stay in this browser tab. Nothing is saved or sent.

Frequently asked questions

Is LiteLLM 1.107.0 the only affected version?

According to the maintainer's report of October 21, 2026, yes, within the stated time windows. Earlier versions and the private Enterprise release were reported as unaffected. The report was still marked investigation in progress at our check on October 24, 2026, so read it again before you rely on this answer.

I uninstalled the package. Is the problem gone?

Not necessarily. Datadog's analysis says the files that run at Python start stay in site-packages after an uninstall. If 1.107.0 ever ran on a machine, follow the maintainer's cleanup, rebuild the environment, and rotate secrets from a different machine.

Does a poisoned package reach my users' phones?

The incidents on this page ran where packages are installed or started: laptops, CI runners, servers and containers, which is where the keys were. If you built an app release while a poisoned dependency was installed, pin a known good version, rebuild and release an update.

What is slopsquatting?

It is registering a package name that an AI model invented, so the next person or agent who runs the install command gets the attacker's code. Aikido documented a case in January 2026 where 237 repositories already pointed at an unpublished name that came from generated agent skill files.

Should I stop using MCP servers and agent skills?

There is no general answer. Treat each one as code that runs with your privileges. Read the start command, pin the version, give it only the keys it needs, and check that any package name it installs exists and belongs to the publisher you expect.

Can the red.run.cloud scan see any of this?

Only part of it. The scans work from outside your live site, so they cannot read your lockfile, CI workflows or laptop. They can show readable .env and .git paths and keys in shipped bundles. Everything else on this page stays unknown until you check it.

Sources

Checked October 24, 2026. Vendor statements are labelled as the vendor's own.

  1. Security incident, October 21, 2026, LiteLLM
  2. LiteLLM 1.107.0 supply chain compromise, Datadog Security Labs
  3. Incident report: LiteLLM and Telnyx supply chain attack, Python Package Index blog, April 2, 2026
  4. GHSA-69fq-xp46-6x23 (CVE-2026-33634), Trivy supply chain, Aqua Security on GitHub
  5. ChainDrop supply chain compromise, August 4, 2026, Microsoft Security Blog
  6. Slopsquatting via hallucinated agent skills, Aikido Security
  7. Malicious postmark-mcp package on npm, Snyk
  8. Authorization, specification 2026-07-28, Model Context Protocol
  9. Security best practices, local MCP server compromise, Model Context Protocol
  10. Security hardening for GitHub Actions, GitHub Docs
  11. Secure installs and hash-checking mode, pip documentation
  12. Trusted Publishing, PyPI documentation
  13. npm ci, npm documentation
  14. npm config: min-release-age and ignore-scripts, npm documentation
  15. npm install-time security changes, July 8, 2026, GitHub Changelog
  16. Tags and digests, Docker documentation
  17. LLM03:2025 Supply Chain, OWASP GenAI Security Project
  18. Environment variables in Expo, Expo docs

Continue Learning