AI Agent Supply Chain Attacks: Malicious Packages Guide
How AI agent supply chain attacks work: malicious npm and PyPI packages, typosquatting, compromised dependencies and install scripts, plus how to defend.
Part of our guide to AI Agent Security: How to Vet an Agent Before Install.
An AI agent supply chain attack happens when the code you install, or something it depends on, has been made malicious before it reaches you. For agents and MCP servers this usually means a fake package with a convincing name, a real package whose maintainer account was taken over, a poisoned dependency, or an install script that runs the moment you type npm install or npx.
The fix is not one tool. It is a habit: verify the publisher, avoid running install scripts you have not read, pin versions, scan dependencies, and run new tools in a sandbox with scoped credentials. This article explains each attack and the defence that matches it. It is part of our guide on how to vet an AI agent before you install it.
Why agents make supply chain attacks worse
Most MCP servers and many agents are distributed as npm or PyPI packages and launched with a single command such as npx some-server or uvx some-server. That command downloads the latest version and runs it with your user's permissions. No review step, no prompt. An MCP server runs with your user's permissions.
Once running, the tool often holds API keys, OAuth tokens and access to your files. OWASP lists Supply Chain as LLM03 in its 2025 Top 10 for LLM applications for this reason.
Attack 1: Fake packages that impersonate real ones
The simplest attack is to publish a package that looks official. Users search the registry, see a familiar brand name, and install it.
The best documented agent example is postmark-mcp. In September 2025, researchers at Koi Security reported a package on npm that copied the code of a legitimate Postmark email tool. According to The Hacker News report, it behaved normally across 15 versions to build trust, then version 1.0.16 added a single line that blind-copied every email sent through it to an attacker's address. Postmark said it had no involvement with the package.
Defence:
- Check that the package's repository URL points to the vendor's official GitHub organisation.
- Prefer install instructions from the vendor's own docs over registry search results.
- Compare the published tarball with the repository source (
npm pack <name>@<version>downloads it without installing).
Attack 2: Typosquatting
Typosquatting relies on a typo or a plausible variant: crossenv instead of cross-env, an extra hyphen, a swapped letter, or -mcp added to a brand name.
This is an old trick. In 2017 npm removed a set of packages, including crossenv, that sent environment variables from the install machine to a remote server. npm advised anyone who installed them to rotate every credential in their shell environment. The same idea works today against MCP server names, which are new, numerous and not yet familiar to most users.
Agents add a new twist: an AI coding assistant may suggest a package name that sounds right but does not exist, or does not belong to who you think. Always check a suggested package before you run it.
Defence:
- Copy package names from official docs, never type them from memory.
- Before installing, run
npm view <name>or check the PyPI page. Look at the publisher, creation date and download history. - Be suspicious of packages that are very new but claim to be official.
Attack 3: Compromised maintainers and dependencies
Sometimes the package is real but the account that publishes it is not under the owner's control any more. Attackers phish maintainers, steal tokens from CI systems, or take over abandoned packages.
In September 2025, CISA published an alert on a widespread npm compromise involving a self-replicating worm known as Shai-Hulud, which spread by abusing developer credentials and publishing malicious versions of existing packages. You did not need to install anything unusual to be affected. A normal update was enough.
The clearest 2026 example hit an AI tool directly. On March 24, 2026, backdoored versions 1.82.7 and 1.82.8 of LiteLLM, a widely used Python library for calling LLM APIs, were published to PyPI. The chain started elsewhere: attackers tracked as TeamPCP abused a pull_request_target workflow in the Trivy security scanner's repository, stole credentials and pushed a malicious Trivy release. LiteLLM's CI installed Trivy without pinning a version or checking a checksum, so it ran the compromised scanner, which stole the PyPI publishing token (JFrog, Snyk). The payload collected SSH keys, cloud and Kubernetes credentials, .env files and wallet files, sent them to a look-alike domain, and installed a persistent backdoor. Version 1.82.8 used a .pth file, which runs on every Python startup, so it could run without LiteLLM ever being imported. Snyk reports the versions were available for about three hours before PyPI quarantined the package.
The lesson for agent builders: an unpinned tool in your CI is part of your supply chain, even a security tool.
Deep dependencies are a quieter version of the same problem. Your MCP server may have five direct dependencies and hundreds of transitive ones. The xz Utils backdoor (CVE-2024-3094) showed that a trusted, long-maintained project can ship malicious code through its normal release process.
Defence:
- Pin exact versions and commit lockfiles. In MCP client configs, use
some-server@1.4.2rather than a bare name or@latest. - Install from the lockfile in automation with
npm ci, which fails ifpackage.jsonand the lockfile disagree. - Scan dependencies for known vulnerabilities and malicious package advisories, for example with
osv-scanner scan source -r .. - Pin CI tools too. Scanners, linters and GitHub Actions that run with publishing secrets should be pinned to a version or commit, as the LiteLLM case shows.
- Wait before upgrading to brand new releases of tools that hold sensitive access. A short delay gives maintainers and security researchers time to spot and pull a bad release.
Attack 4: Install scripts
npm packages can declare preinstall, install and postinstall scripts. Python packages can run arbitrary code in setup.py. These run automatically during installation, with your permissions, before you call a single tool.
A malicious install script might look harmless at a glance:
"scripts": {
"postinstall": "node scripts/setup.js"
}
Then setup.js reads ~/.npmrc, ~/.aws/credentials or process.env and posts them somewhere. The crossenv packages above worked this way.
Defence:
- Read every install script before you install a new package.
- Install with scripts disabled when you can, then run only the ones you have reviewed:
npm install --ignore-scripts
npm documents this in its ignore-scripts config option. Some packages with native code will need scripts to build, so review those individually.
Attack 5: Code fetched at runtime
A package can be clean at install time and still download and run code later. Watch for fetch or curl of a script followed by eval, new Function, exec, or writing a file and running it. Static scanners can flag the pattern, but they cannot see what the remote server will send tomorrow.
Code is not the only thing fetched at runtime; tool descriptions can change too, see MCP tool poisoning. An MCP server's tool names and descriptions are text the model reads and follows, and a server can return different ones after you approved it. Content the agent reads while working, such as web pages and issues, is a related vector covered in prompt injection in tool-using agents.
Defence: run new agents in a container with outbound traffic recorded, and compare the domains it contacts with the ones it documents. Undeclared domains and raw IP addresses are a strong signal something is off.
Attack 6: Poisoned models and model files
Agents that download models add another link to the chain. Two problems apply:
- Model files that run code. Some model formats, such as PyTorch files saved with Python's pickle, can execute code when loaded. In February 2024 JFrog reported around 100 malicious models on Hugging Face; one opened a reverse shell to a remote IP address as soon as it was loaded.
- Backdoored weights. A fine-tune can behave normally until a trigger phrase appears. OWASP covers this as LLM04 Data and Model Poisoning.
Defence: download models only from the publisher's own organisation account, prefer safetensors, a format built to store tensors safely as opposed to pickle, and pin the exact model revision.
Keep an AI bill of materials
A software bill of materials lists your packages. An AI bill of materials (AIBOM) adds the models, datasets and their versions and sources. CycloneDX, an OWASP standard, defines a Machine Learning Bill of Materials (ML-BOM) format for models, datasets and their dependencies. For a small agent project, even a checked-in list works: each MCP server and version, each skill and commit, each model and revision, and where each came from. When an advisory like the LiteLLM one appears, you can answer "are we affected?" in minutes.
How this maps to OWASP and NIST
| Framework | What it covers | Attacks here |
|---|---|---|
| OWASP LLM03 Supply Chain | Third-party packages, models and data in LLM applications | 1 to 5 |
| OWASP LLM04 Data and Model Poisoning | Tampered training data and model weights | 6 |
| NIST AI 100-2 E2025 | Adversarial Machine Learning: A Taxonomy and Terminology of Attacks and Mitigations (March 2025) | 6, and the vocabulary for reports |
A practical defence checklist
| Stage | What to do |
|---|---|
| Before install | Verify publisher and repo, read install scripts, diff package vs source. Compare install commands against the publisher's repo on the MCP server directory |
| Install | Use --ignore-scripts, pin exact versions, commit lockfiles |
| First run | Sandbox it, drop privileges, record network traffic |
| Credentials | Give it a scoped token, not your main key |
| Updates | Read the changelog and diff, rescan, then upgrade |
Limiting credentials matters because supply chain attacks often succeed before any review catches them. A stolen token with read access to one repository is a small incident. A stolen admin token is a large one. Our guide to least privilege for AI agents shows how to scope them.
On AgenticMart, any listing can get a free automated scan; each listing page shows its scan status. A scan covers several of these checks automatically: Semgrep rules for eval, shell execution, hidden environment variable reads and obfuscation; Gitleaks for secrets; OSV-Scanner for known-vulnerable dependencies; and a sandboxed install and start with outbound traffic compared against the manifest. It runs on a fresh virtual machine that is destroyed afterwards. A scan reflects the version it tested, so re-check when you upgrade.
FAQ
What is a software supply chain attack in AI agents?
It is an attack that compromises an agent, MCP server or skill before it reaches you, through a fake package, a hijacked maintainer account, a malicious dependency or an install script. Because agents run with your permissions and often hold API keys, the impact can be large.
How do I protect against typosquatting on npm?
Copy package names from the vendor's official docs, check the publisher and repository with npm view before installing, and be wary of very new packages that claim to be official. Pinning versions and disabling install scripts adds another layer.
Is it safe to use npx to run MCP servers?
npx downloads and runs code in one step, so it is only as safe as the package you name. Pin an exact version, verify the publisher first, and consider running the server in a container. Our MCP server install guide covers safer setups.
What happened in the LiteLLM supply chain attack?
On March 24, 2026, attackers published backdoored LiteLLM 1.82.7 and 1.82.8 to PyPI using a token stolen through a compromised Trivy scanner in LiteLLM's CI. The versions stole credentials and installed a backdoor. If you installed either, JFrog's write-up advises treating the machine's credentials as compromised and rotating them.
Are AI models part of the supply chain?
Yes. Model files can run code when loaded, and fine-tuned weights can hide a backdoor. Download models from the publisher's own account, prefer safetensors over pickle-based formats, and pin the revision you tested.
Can a dependency scanner catch malicious packages?
Partly. Tools like OSV-Scanner match your dependencies against known vulnerability and malware advisories, so they catch packages that have already been reported. They cannot catch a brand new malicious release that nobody has flagged yet, which is why sandboxing and least privilege still matter.
Browse agents, MCP servers and skills on AgenticMart, see what each can touch, and explore the newest standards on our agent protocol map. List yours free now, paid selling opens soon.