Your Package Manager Is an Attack Vector. Are Your Developers Ready?
In 2021, a security researcher published a paper demonstrating that he could execute code inside Apple, Microsoft, and Tesla by exploiting how package managers resolve dependencies. He called it dependency confusion. It was elegant, it was devastating, and it required no zero-days — just a package name and a public registry.
Four years later, the technique has been refined, automated, and weaponised by real threat actors. And the average development team still runs npm install without thinking about where those packages actually come from.
How dependency confusion works
Most organisations use a mix of public and private packages. The private ones live on an internal registry — a private npm, PyPI, or Maven repository. The public ones come from the public registry. When a developer runs an install command, the package manager needs to decide: for each dependency, should I fetch from the private registry or the public one?
The answer depends on the package manager's resolution logic. And in many configurations, the answer is: whichever version is higher. An attacker who knows the name of an internal package — often guessable from GitHub repos, job postings, or error messages — publishes a package with the same name to the public registry with a very high version number. The package manager fetches the attacker's version. The install script runs. The attacker has code execution in your build pipeline.
No exploit required. No vulnerability in your code. Just a misunderstanding of how package resolution works.
Typosquatting: the low-effort variant
Dependency confusion requires knowing an internal package name. Typosquatting requires nothing — just patience. An attacker publishes a package called expresss (three s's), or lodahs, or react-routter. A developer makes a typo. The malicious package installs. Its post-install script exfiltrates environment variables — which typically include database credentials, API keys, and cloud access tokens.
The npm registry has seen thousands of typosquatting packages. PyPI has seen thousands more. Some are caught quickly. Some sit for months before anyone notices. The ones that target niche packages with smaller communities can persist even longer.
A developer who has been trained to verify package names, check download counts, inspect maintainer history, and review install scripts catches this. A developer who hasn't just types npm install and moves on.
The lockfile is not a silver bullet
Teams often point to lockfiles as the mitigation for supply chain attacks. And lockfiles do help — they pin exact versions and prevent unexpected upgrades. But lockfiles only protect you after the first install. If the first install pulls a malicious package, the lockfile dutifully records that malicious version and ensures every team member and CI pipeline gets the same compromised dependency.
Lockfiles also don't protect against maintainer account compromises. When a legitimate package maintainer's credentials are stolen and a backdoor is published as a patch version, the next developer who runs npm update pulls the backdoor. The lockfile updates. The compromised version propagates across the team.
The event-stream incident in 2018 demonstrated this. A widely-used npm package was transferred to a new maintainer who added a targeted backdoor. Millions of installs happened before it was discovered. Lockfiles didn't help because the malicious code was in a legitimate version from a legitimate-looking maintainer.
What developers actually need to know
Supply chain security isn't just a tooling problem. It's a knowledge problem. Developers need to understand the mechanics of how these attacks work so they can recognise risk signals in their daily workflow.
They need to know what scoped packages are and why using them for internal packages eliminates an entire class of dependency confusion attacks. They need to understand that a package with 12 weekly downloads and a single maintainer who created their account last Tuesday is not the same risk profile as a package maintained by a foundation with 10 million weekly downloads.
They need to be trained on reviewing what happens during install. Most developers have never looked at a post-install script. Most malicious packages rely on that.
Build pipeline as blast radius
The reason supply chain attacks are so dangerous isn't just that they get code onto a developer's machine. It's that they get code into the build pipeline. And the build pipeline has access to everything: deployment credentials, signing keys, production environment variables, artifact registries.
A compromised dependency that runs during CI has the same access as your deployment scripts. It can exfiltrate secrets, inject backdoors into build artifacts, or modify the deployed application without touching a line of your source code. Your git history looks clean. Your diffs look clean. The deployed binary is compromised.
This is why supply chain security belongs in AppSec training, not just in DevOps tooling discussions. Every developer who adds a dependency is making a trust decision. They should be equipped to make that decision with the same rigour they apply to writing authentication code.
Start with awareness, then build habits
The organisations that handle supply chain risk well share a common trait: their developers treat dependencies as code they're responsible for, not code someone else is responsible for. They review new dependencies before adding them. They audit existing dependencies periodically. They understand that every package in their lockfile is a trust relationship with an external maintainer they've never met.
That mindset doesn't come from a policy document. It comes from training that shows developers what a supply chain attack actually looks like — how dependency confusion is executed, how typosquatting works, what a malicious install script does. When a developer has exploited these techniques in a training environment, they recognise the risk signals in their real environment.
Your next breach might not start with a SQL injection or a stolen password. It might start with npm install.
Want to train your team on this?
20 minutes. Bring a real PR. We'll show you what your team is shipping past.
Book a 20-min demo