Modern software isn't written, it's assembled. A typical application pulls in hundreds of third party dependencies, and each one is a door. Attackers know this, and so does the industry: in its 2025 update, OWASP itself moved software supply chain failures up to third place on its list of most critical risks, with half of the experts surveyed ranking it their top concern.
That concern has been confirmed many times over. In 2025 alone, more than 450,000 new malicious packages were identified, npm suffered the first self replicating worm in its history, and state linked groups compromised libraries with more than 100 million weekly downloads. In this article you'll find the three families of attack that dominate this space (typosquatting, dependency confusion, and slopsquatting), where the technique comes from, the most relevant real world cases from the last few years, and how to harden your pipeline. Because a classic vulnerability scanner, on its own, won't save you from this.
In this guide
- Why the supply chain is the perfect target
- The origin: from research to industrialization
- The three families of attack
- Technical anatomy of a dependency confusion attack
- Real cases from 2022 to 2026
- Why your scanner won't save you
- How to harden your pipeline
- What this means for your career in offensive security
- Where to start
- Frequently asked questions
Why the supply chain is the perfect target
More than 85% of companies use open source software, and any given project can pull in hundreds of packages that, in turn, pull in others. That implicit trust is the crack. If an attacker manages to slip code into a popular dependency (or into one that looks close enough), that code runs on thousands of machines during a routine install.
And here's the uncomfortable part: the malicious package can be signed with a valid key, published by a legitimate account, and distributed over HTTPS. Traditional signature verification doesn't catch it, because the problem isn't that the package gets tampered with in transit, it's that the source itself is hostile, or that the publishing process (a maintainer account, a CI/CD pipeline) has been hijacked. That's exactly why OWASP split supply chain failures (category A03) from software and data integrity failures (category A08) in 2025: one is a question of what code enters your project, the other is a question of whether that code gets altered after it enters.
The origin: from research to industrialization
Dependency confusion wasn't born as a wild attack: it was born as security research. In February 2021, after an eight month research project, a report was published documenting how it was possible to execute code inside the infrastructure of more than 35 large companies (including Apple, Microsoft, PayPal, Shopify, Netflix, Tesla, Uber, and Yelp) simply by publishing public packages with the same name as those companies' private internal packages. The research earned more than $130,000 in bug bounty rewards for the finding.
The mechanism is simple once you understand it: many build systems query several package indexes at once (a private one, with the company's internal dependencies, and the public one, npm or PyPI). If an attacker publishes a package in the public index with the same name and a higher version number than the internal one, the package manager, following its normal "install the most recent version" logic, picks the malicious version. No phishing, no social engineering, no exploiting any code vulnerability: just a guessed name and a version number.
The finding triggered a wave of research on the topic and led npm and other package managers to introduce mitigation mechanisms, such as namespaced (or "scoped") packages explicitly mapped to a specific registry. But the theory took less than two years to turn into a real attack outside the lab, as you'll see in the real cases section.
The three families of attack
On top of that technical foundation, three variants have been built that, while they share a goal (getting you to install something you didn't mean to install), exploit different failure points: a human's eye, a package manager's configuration, or the language model that suggests what to install.
1. Typosquatting
The attacker publishes packages with names one character away from popular ones, betting on haste and clumsy fingers. Variants of requests, boto3, or numpy with tiny typos have all been seen in the wild. The payload pattern is consistent: a script that runs at install time (a postinstall hook in npm, or module level code that fires on import in Python), which exfiltrates environment variables and SSH keys, and sometimes leaves a persistence mechanism behind.
Classic typosquatting depends on human error, but its increasingly common cousin (hijacking a legitimate maintainer account through phishing) doesn't even need that. In 2025, a phishing campaign that impersonated npm and asked maintainers to "update" their two factor configuration was, according to the researchers who documented the case, the likely entry point for several of the year's most serious attacks: the package name doesn't change, but whoever publishes it isn't who you think anymore.
2. Dependency confusion
You've already seen where this technique comes from. In practice, it stays relevant because many companies still have internal packages (say, mycompany-utils) without reserving the equivalent name on the public registry. If an attacker publishes that same name on npm or PyPI with a higher version number, a misconfigured package manager may prefer the public one. In 2026, targeted attacks trawl job postings, GitHub repositories, error messages in public issues, and Docker layer metadata to discover those internal names before registering them first.
3. Slopsquatting (hallucinated packages)
The AI era variant. Generative code assistants hallucinate (invent) package names that don't exist, at a higher rate than you'd expect: an academic study presented at USENIX Security 2025, which analyzed 576,000 code samples generated by 16 different models, found that 19.7% of recommended packages didn't exist. Open source models hallucinated more (21.7% on average) than closed, commercial models (5.2%), and more than 205,000 distinct hallucinated package names were identified overall.
What turns this into an attack vector, rather than just a funny glitch, is that the hallucinations repeat: more than half of the invented names reappeared across different runs of the same model. The term was coined in April 2025 out of the Python Software Foundation and quickly caught on in the security community. There was already a real world precedent proving the problem in practice: in 2023, it was observed that several models kept insistently recommending a Python package called huggingface-cli, which doesn't exist (the real command installs as part of huggingface_hub[cli]). As a test, an empty package was published under that name just to measure real interest, and in three months it racked up more than 30,000 downloads.
Typosquatting no longer just aims to confuse the human: now it also aims to confuse the model, and the model, unlike a developer in a hurry, has no instinct of suspicion toward a name that "sounds right".
# The three ways you end up installing malicious code Typosquatting requets (instead of "requests": a typo) Dependency conf. mycompany-utils (your internal package, cloned in the public repo) Slopsquatting auto-fetch-lib (a name the AI made up and an attacker registered)
| Vector | Who it fools | What it exploits | Main defense |
|---|---|---|---|
| Typosquatting | The developer (typo) or their account (phishing) | Typing mistakes or stolen maintainer credentials | Hardware or TOTP MFA, name review |
| Dependency confusion | The package manager | The "highest version wins" logic when resolving a name across several indexes | Reserve the public namespace, a single index with explicit priorities |
| Slopsquatting | The AI model (and, through it, the developer) | The hallucination rate of package names in LLMs | Verify every suggested package before installing it |
Technical anatomy of a dependency confusion attack
To understand why this family of attacks works, it helps to see the full sequence, as it was described in the original research and as it later played out in the real world:
- The company has an internal package, say
@mycompany/auth-utils, hosted on a private registry (Artifactory, Nexus, an Azure DevOps feed). - The build pipeline is configured to query both the private and the public registry, sometimes without anyone explicitly deciding that: it just comes that way by default or out of convenience.
- The attacker figures out the exact name of the internal package (a leaked
package.jsonon GitHub, a job posting that mentions the library, a Docker error, or simply guessing common names) and publishes a public package with that same name and a higher version. - The next time someone runs
npm installorpip install, the package manager resolves the name by querying both indexes and keeps the highest version: the attacker's. - The attacker's code runs with the same privileges as the build process, typically inside a CI/CD pipeline with access to secrets, tokens, and deployment credentials.
# Insecure pip configuration: queries both indexes without distinguishing the source $ pip install internal-library --extra-index-url https://pypi.org/simple/ ← pip treats both indexes equally and may prefer the public one # Secure npm configuration: the organization's scope is ALWAYS served # from the private registry, never from the public one (.npmrc file) @mycompany:registry=https://npm.mycompany.internal/ //npm.mycompany.internal/:_authToken=${NPM_TOKEN} ← any package under @mycompany/* can only come from that registry
--extra-index-url flag is, by design, inherently insecure: it does exactly what it promises (search more than one index), just not in the order most developers assume.Real cases from 2022 to 2026
The academic origin of the technique hasn't taken any of the real danger away from it. These are the cases that mark its evolution from the first documented compromise to today.
torchtriton (December 2022): the jump from the lab to the real world
Between December 25 and 30, 2022, someone published a package called torchtriton on PyPI, the same name as a dependency that PyTorch distributed only from its own nightly build index. Since PyPI takes precedence in pip's resolution, anyone installing PyTorch nightly on Linux during those days received the malicious version instead of the legitimate one.
The fake package exfiltrated environment variables, the hostname, SSH keys, and the contents of the first files in the home directory, all via DNS to a domain registered just days before the attack. It was downloaded several thousand times before being taken down. Whoever was behind the package later claimed it was security research that had gotten out of hand, but the PyTorch team treated it as what it was: a real compromise. They renamed the legitimate dependency to pytorch-triton and registered a decoy package on PyPI so the same name couldn't be hijacked again.
Shai-Hulud (September and November 2025): npm's first self replicating worm
On September 15, 2025, researchers detected the first self replicating worm in npm's history. The entry point is believed to have been a phishing campaign that impersonated npm and asked maintainers to "update" their two factor configuration; whoever took the bait handed over their credentials. The package rxnt-authentication, published on September 14 from the techsupportrxnt account (the campaign's "patient zero"), was the starting point.
From there, the malware (named Shai-Hulud, after the sandworms in Dune) did something no previous large scale npm attack had done: propagate on its own. Once an infected package was installed, the script stole npm and GitHub tokens, AWS and GCP credentials, and used TruffleHog to hunt for additional secrets on the system. With the stolen npm token, the malware authenticated as the legitimate maintainer, injected its own code into any other package that person could publish, and republished trojanized versions without any human intervention. It also created a public GitHub repository called "Shai-Hulud" containing the stolen secrets encoded in Base64.
The first wave hit more than 500 packages, including @ctrl/tinycolor (more than two million weekly downloads) and several packages owned by CrowdStrike. Two months later, on November 24, 2025, a much more aggressive variant known as Shai-Hulud 2.0 appeared: it ran its payload during the pre install phase (before the install finishes, widening the impact window), added a destructive fallback that could wipe the user's home directory if it failed to steal credentials, and ended up generating more than 25,000 malicious GitHub repositories across roughly 350 different users.
axios (March 2026): when a state backed group targets your HTTP client
On March 31, 2026, between 00:21 and 03:20 UTC, an attacker published two trojanized versions of axios (the most widely used HTTP library in JavaScript, with more than 100 million weekly downloads and present in around 80% of cloud environments) after compromising its lead maintainer's npm account. The malicious versions added a made up dependency, plain-crypto-js, whose only purpose was to run a post install script that deployed a cross platform remote access trojan (Windows, macOS, and Linux).
Google Threat Intelligence Group and Microsoft independently attributed the attack to a North Korea linked, state backed group (tracked as UNC1069 by Google and as Sapphire Sleet by Microsoft), with a history of cryptocurrency theft. The malicious versions were live for just over three hours before being pulled, long enough that, according to Wiz's estimates, around 3% of axios's user base downloaded them. The case is a good reminder that even modern protections aren't foolproof on their own: the project used OIDC (Trusted Publishing) for its automated releases, but the GitHub Actions workflow still exposed, as a fallback, a classic, long lived npm token; the attacker used that stolen token to publish manually, bypassing the secure flow entirely.
TanStack, Mistral AI, and UiPath (May 2026): the campaign that jumped from npm to PyPI in hours
On May 11, 2026, a group tracked as TeamPCP (also known as UNC6780) compromised TanStack's GitHub Actions pipeline through a chain of vulnerabilities: it forked the repository, opened a pull request that triggered a pull_request_target workflow, and poisoned the pnpm cache that workflow restored. When a legitimate maintainer later merged changes, the poisoned cache was restored and the attacker's code extracted OIDC tokens directly from the GitHub Actions runner's process memory.
With those tokens, the attacker published hundreds of malicious versions across more than 150 npm package names (inside the @tanstack organization, plus packages from UiPath, the Mistral AI SDK, OpenSearch, and other projects), and, hours later, the attack jumped to PyPI with malicious versions of mistralai and guardrails-ai. It was one of the first campaigns to cross from npm to PyPI within the same incident. The most uncomfortable part of the case: since the packages were published from inside a legitimate GitHub Actions runner using valid OIDC tokens, they carried technically correct provenance attestations. Provenance alone isn't a safety guarantee if what's compromised is the very pipeline that generates it.
The bigger picture, in numbers
These cases aren't isolated anomalies: they're the visible tip of a trend the aggregate data confirms. According to Sonatype's State of the Software Supply Chain 2026 report, more than 454,000 new malicious packages were identified in 2025 alone, bringing the cumulative total blocked across npm, PyPI, Maven Central, NuGet, and Hugging Face to over 1.233 million packages: a 75% jump over the previous year. More than 99% of that open source malware was concentrated on npm, and self replicating worms alone added more than 171,000 malicious packages to the registry within a few months.
And that's without counting other campaigns from the same period: TrapDoor spread 34 malicious packages across npm, PyPI, and Crates.io targeting crypto, DeFi, and Solana developers; in June 2026, 32 packages under the @redhat-cloud-services npm scope were compromised; and a campaign known as Hades hit bioinformatics packages on PyPI with a multi stage payload designed, among other things, to try to fool AI based triage systems that analyze the package automatically.
Why your scanner won't save you
Software composition analysis (SCA) tools promised to solve this, but most of them are, at their core, CVE matchers: they look at your list of dependencies and cross reference it against the known vulnerability database. A malicious package that's five days old has no CVE attached to it, so it sails right through the filter.
The numbers back this up. When OWASP promoted supply chain failures to category A03 of its 2025 Top 10, it had to do so almost against its own data: it's the category with the fewest mapped weaknesses (CWEs) on the whole list, and barely 11 associated CVEs, and yet it had the highest average impact of all ten, and the one that half of the experts surveyed voted as their top concern. In other words: the industry's own reference framework admits that this is the risk traditional tools detect worst, and the one that hurts most when it lands.
On top of that, there's the slowness of the official scoring system: according to the same Sonatype report cited above, the median time it takes the NVD to score an open source CVE is 41 days, while a ready to use malicious package can show up in hours. Against these attacks, checking against known CVEs doesn't get you very far.
How to harden your pipeline
What actually works combines entry point control, provenance verification, and behavioral analysis. No single measure is enough on its own:
- Use reproducible installs:
npm ciinstead ofnpm install, and lockfiles with pinned versions, so you install exactly what was verified and fail explicitly on any mismatch. - Own your namespace: register your internal package names on the public registry as a reservation, so no one can impersonate them. This is the direct defense against dependency confusion.
- Force a single index with explicit resolution priorities, so the manager doesn't pick the public package just because it has a higher version.
- Behavioral analysis at install time: watch what a package does when it's installed (outbound network connections, reading keys) and quarantine new packages for a cooling off period.
- Verify what the AI suggests before installing it: that the package exists, that it's the official one, and that it wasn't registered yesterday.
| Measure | Against which attack | How it's applied |
|---|---|---|
| Reproducible installs | Unexpected versions (dependency confusion, compromised account) | npm ci, lockfile with pinned version and integrity, explicit failure on mismatch |
| Reserve the public namespace | Dependency confusion | Register every internal package on npm/PyPI, and use scopes (@mycompany/*) mapped by .npmrc to a single registry |
| Quarantine new packages | Typosquatting, slopsquatting, worms like Shai-Hulud | Block installation of versions published in the last 24-72 hours until they pass an observation period |
| Disable install scripts by default | Payloads in postinstall/preinstall | npm config set ignore-scripts true, explicitly reviewing which packages genuinely need to run code |
| Hardware or TOTP MFA for maintainers | Account hijacking via phishing (the origin of Shai-Hulud and several 2026 cases) | Require it on npm, PyPI, and GitHub; never rely on email verification alone |
| Provenance with caveats (SLSA/Sigstore) | Unauthorized publications | Require provenance attestations, but also audit the pipeline that generates them |
What this means for your career in offensive security
The supply chain is one of the vectors with the most room to grow and the worst coverage, and the data backs that up: it's the category the industry votes as its biggest concern, yet the one where you can least rely on automation alone. Understanding how an attacker reasons about a company's internal names, how code executes during an install, how a maintainer account gets hijacked, or how a CI/CD cache gets poisoned is a highly sought after skill, and it connects directly with the slopsquatting we already covered in the post on AI generated code.
At its core, it's about thinking in terms of trust flows: where each piece of software comes from, who has permission to publish it, and what happens when it runs. If you train that kind of reasoning with the Web eXploitation Expert (WXE) course, you'll have the foundation to audit an application's supply chain too.
Want to learn to think like an attacker in the supply chain too?
At SixHack Academy we train the reasoning around trust boundaries and code execution behind these attacks. The Web eXploitation Expert (WXE) course gives you that foundation.
Where to start
- Audit which internal namespaces your organization uses and check whether their equivalent names are free on npm and PyPI. If they are, that's your first real dependency confusion risk.
- Review your project's package resolution configuration (
.npmrc,pip.conf, your dependency manager's settings) and confirm it doesn't implicitly mix a private index with the public one. - Replace
npm installwithnpm ci(or the equivalent in your package manager) across every CI/CD pipeline. - Check whether your organization requires hardware or TOTP MFA for every maintainer with publish permissions, not just email verification.
- The next time an AI assistant suggests installing a package you don't recognize, look it up before installing it. It's the simplest possible move against slopsquatting.
Frequently asked questions
What's the difference between typosquatting and dependency confusion?
Typosquatting bets on someone misspelling a popular package's name, or directly hijacks a legitimate maintainer's account. Dependency confusion impersonates the name of a private internal package on the public repository, hoping the package manager will prefer the public one for having a higher version number.
What is slopsquatting?
It's registering malicious code under the package names AI assistants invent (hallucinate). The term was coined in April 2025 out of the Python Software Foundation, and a USENIX Security 2025 study found that nearly 1 in 5 packages recommended by 16 different models didn't exist.
Doesn't my security scanner protect me?
Almost never against this. Most scanners check against known CVEs, and a freshly published malicious package has no CVE (the very OWASP category covering these failures has barely 11 CVEs mapped to it). You need install time behavioral analysis and entry point control.
What's the simplest, most effective defense?
Register your internal package names on the public repository (so no one can impersonate them), use reproducible installs with lockfiles, require hardware or TOTP MFA for maintainers, and quarantine new packages before trusting them.
What was Shai-Hulud, and why did it change the rules of the game?
It was the first self replicating worm discovered on npm, in September 2025. Unlike a manual attack, once it stole a maintainer's credentials it published itself, unassisted, into any other package that person had access to, with no need for the attacker to intervene. It hit more than 500 packages in its first wave and spawned a more aggressive, destructive variant two months later.
Do these attacks only affect npm and PyPI?
No, although those are the ecosystems where most documented cases concentrate (npm by volume, PyPI by payload precision). Campaigns have already been seen crossing into Crates.io, NuGet, and Packagist, and 2026 industry reports track malware on Maven Central and Hugging Face as well.
Can AI make this problem worse, beyond slopsquatting?
Yes, on a second, less obvious front: when an AI selects or updates dependencies without real time verification, it can recommend versions that don't exist or packages already flagged as malicious. A 2026 industry report found that, without that verified context, a state of the art model hallucinated around 28% of component versions when recommending dependency updates.
References
- OWASP Top 10:2025, A03: Software Supply Chain Failures: the category that moved supply chain failures to third place among the most critical risks in 2025.
- Original 2021 publication on the dependency confusion technique.
- PyTorch: official notice on the torchtriton compromise (2022).
- Wiz: analysis of the Shai-Hulud worm (2025).
- Google Threat Intelligence Group: attribution of the axios attack (2026).
- SafeDep: analysis of the TanStack / Mistral AI / UiPath campaign (2026).
- Sonatype, State of the Software Supply Chain 2026: Open Source Malware.
- Wikipedia: "Slopsquatting", on the origin of the term and a summary of the USENIX Security 2025 study.
- npm: npm ci: reproducible installs from the lockfile.
- GitGuardian: analysis of typosquatting and dependency confusion attacks.