Caloogy Article
中文

Dependency Poisoning and Typosquatting

Date
Oct 5, 2026
Series
Infra
Reading
4 min
Topics
InfraSupply chainNpmPypi

The one-sentence version

Over 90% of modern software code comes from third-party dependencies. If even a single package is poisoned, every project using it will be compromised. Common methods include: Typosquatting (registering a name that differs by only one letter from a famous package), Account Takeover (stealing or tricking maintainers out of their accounts), Long-term Dormancy (gaining trust as a contributor over several years before planting a backdoor), and Dependency Confusion (tricking build tools into downloading a malicious package with the same name from a public repository instead of an internal one). The 2024 xz-utils backdoor is the most alarming example: an attacker spent about two years becoming a maintainer and nearly succeeded in introducing a backdoor into mainstream Linux distributions.

This article has three layers:

  1. Layer 1: The Intuition: A restaurant's ingredients come from hundreds of suppliers
  2. Layer 2: Real-World Use: event-stream, ua-parser-js, xz-utils, dependency confusion
  3. Layer 3: Principles and Engineering Key points

Layer 1: The Intuition

1.1 Hundreds of Suppliers

A restaurant's dishes rely on ingredients from hundreds of suppliers, and those suppliers have hundreds of suppliers of their own. If any single one of them adulterates the raw materials, every restaurant using that batch of materials will face trouble.

An ordinary JavaScript project has dozens of direct dependencies, which can expand to thousands of indirect dependencies. You may have never actually read the code for a single one of them.

1.2 Four Methods of Poisoning

Method Analogy
Typosquatting Opening a shop called "Coca-Colla"
Account Takeover Stealing the official seal of a legitimate supplier
Long-term Dormancy Applying to work for a legitimate supplier, working for two years to become a manager, and then adulterating the raw materials
Dependency Confusion Your company has an internal recipe called "Secret Sauce," but someone registers a product with the same name externally, and the procurement officer buys the wrong one

Layer 2: Real-World Use

Event Method Process
event-stream (2018) Maintenance Handover The original maintainer had no time to maintain the package and handed this npm package, which is downloaded millions of times weekly, to a stranger who offered to help. The new maintainer added a dependency containing malicious code specifically targeting a Bitcoin wallet application to steal users' wallets.
ua-parser-js (2021) Account Takeover The maintainer's npm account was compromised, and the attacker published versions containing a miner and a password stealer.
Dependency Confusion (2021) Same-named Public Package Security researchers discovered that many companies' build systems, when looking for internal packages, would prioritize downloading a higher version number package with the same name from public repositories. They used this (in a harmless way) to enter the internal networks of dozens of large companies, earning significant bug bounties.
xz-utils (2024, CVE-2024-3094) Long-term Dormancy A developer using a pseudonym spent about two years contributing code to this fundamental compression library to gain the trust of maintainers, eventually planting a complex backdoor targeting SSH within the release package (rather than the source repository). Microsoft engineer Andres Freund discovered it after noticing that SSH logins were about half a second slower and CPU usage was abnormal. By then, the backdoor had already entered the testing versions of several distributions.

The xz incident exposed a structural problem in open-source infrastructure: a vast number of critical components are maintained by one or two exhausted volunteers.


Layer 3: Principles and Engineering

3.1 Installation is Execution

Many package managers allow packages to run scripts during installation (such as npm's postinstall or Python's setup.py). This means: npm install a certain package is equivalent to executing the code written by the author on your computer under your identity. You don't even need to actually call the package.

Countermeasure: Disable installation scripts in CI and in environments where they are not needed (such as npm ci --ignore-scripts), and only allow them for packages that strictly require them.

3.2 Lockfiles and Hashes

Measure Function
Lockfiles (package-lock.json, poetry.lock, Cargo.lock) Fix the exact version of every dependency (including indirect dependencies)
Integrity Hash The lockfile records the hash of each package; it is verified after downloading to prevent the same-version file in the repository from being replaced
Use ci instead of install in CI Installs strictly according to the lockfile; errors out if the lockfile and manifest are inconsistent
Updates must be reviewed Dependency updates should go through human-reviewed PRs to check the content of changes, rather than being merged automatically

3.3 Preventing Dependency Confusion

3.4 Identifying Suspicious Packages

Signal Description
Name is extremely similar to a famous package typosquatting
Recently released, low download count, yet introduced by your dependency Might be a newly planted malicious dependency
Recent change in maintainer The lesson from event-stream
New version suddenly adds installation scripts, network requests, or obfuscated code High risk
Published package content is inconsistent with the source repository The xz backdoor existed only in the release package

There are specialized tools and services (such as Socket, OpenSSF Scorecard, and various platform-specific dependency scanners) that can automatically check for these signals.

3.5 SBOM and Long-term Measures


Summary

Layer Key points
Risk Thousands of dependencies; any single one being poisoned will cause a compromise
Methods Typosquatting, Account Takeover, Long-term Dormancy, Dependency Confusion
Key Fact Installation is execution
Countermeasures Lockfiles + Hashes; Disable installation scripts; Scopes + Private mirrors; Review updates; SBOM and Provenance