Supply Chain Attacks on npm and PyPI: What Changed in 2025
Typosquatting, dependency confusion, and the compensating controls we now recommend by default.

The digital ecosystem's increasing reliance on open-source software distributed through package managers like npm and PyPI has, by 2025, ushered in a new era of supply chain vulnerabilities. The year 2025 notably marked a sharp and alarming rise in supply chain compromises specifically targeting these ubiquitous registries. This escalation necessitates a fundamental shift in defensive postures: security professionals and developers alike must now operate under the explicit assumption that any new dependency incorporated into a project is hostile until proven otherwise. This paradigm shift moves beyond mere diligence to an active, inherent distrust, demanding robust compensating controls to mitigate the substantial risks.
The primary vectors for these attacks in 2025 continued to be sophisticated variations of well-known techniques:
- Typosquatting: Threat actors registered package names remarkably similar to popular or commonly misspelled legitimate packages, often with a single character difference. Unwitting developers, typing quickly or making minor errors, would inadvertently install these malicious versions, granting attackers initial access or executing harmful payloads.
- Dependency Confusion: Leveraging scenarios where private and public packages share the same name, attackers exploited package manager resolution logic. By publishing a malicious package to a public registry with the same name as an organization's internal, proprietary package, they could trick build systems into downloading and executing the public, malicious version instead of the intended private one.
- Malicious Package Injection: This involved direct compromise of maintainer accounts or the package registry infrastructure itself, though less common than typosquatting or dependency confusion. When successful, attackers could inject malicious code into legitimate, widely-used packages, affecting countless downstream projects.
These attack methods, coupled with the sheer volume of new packages and updates daily, made 2025 a pivotal year, illustrating that reactive security measures are no longer sufficient. Organizations must proactively implement comprehensive safeguards to harden their software supply chains.
Controls Worth Adopting
Given the heightened threat landscape, several crucial controls have transitioned from best practices to essential, mandatory components of any secure development lifecycle. These are not merely recommendations but foundational requirements for maintaining integrity and trust in software dependencies.
-
Pin versions and verify integrity hashes in lockfiles. Explicitly define and "pin" every dependency to an exact version number within your project's manifest files (e.g.,
package.jsonfor npm,pyproject.tomlorrequirements.txtfor PyPI). This prevents automatic updates to potentially compromised newer versions of a package. Furthermore, utilize lockfiles (e.g.,package-lock.json,yarn.lock,poetry.lock) to store cryptographic integrity hashes (e.g., SHA512) for every dependency, including transitive ones. During subsequent installations, the package manager verifies that the downloaded package's hash matches the one recorded in the lockfile, immediately detecting if the package has been tampered with or replaced on the registry. -
Use a private registry proxy with allowlisting. Implement an internal private registry proxy (such as Nexus Repository Manager or Artifactory) that acts as an intermediary between your development environment and public registries like npmjs.com or pypi.org. This proxy should operate in an allowlisting mode, meaning developers can only install packages that have been explicitly approved and added to the organization's internal, curated list. All new package requests undergo a mandatory security review process, including vulnerability scanning and trust assessment, before being permitted into the internal proxy. This significantly reduces the attack surface by preventing the download of unknown or unvetted packages.
-
Block install scripts by default; opt in per package. Many package formats, particularly in the npm ecosystem, allow for the inclusion of arbitrary install scripts that execute automatically upon package installation. These scripts are a prime vector for malicious payloads. Configure your package manager (e.g., using
--ignore-scriptsfor npm) to disable the automatic execution of these scripts by default. If a package genuinely requires an install script for functionality, explicitly review its contents and only enable it for that specific, validated package, potentially within a sandboxed environment. This proactive measure prevents silent execution of malicious code during dependency installation. -
Scan SBOMs against advisory feeds in CI. Incorporate comprehensive Software Bill of Materials (SBOM) generation and scanning into your Continuous Integration (CI) pipelines. An SBOM provides a complete, machine-readable inventory of all components within a software product, including direct and transitive dependencies. Once generated, these SBOMs should be continually scanned against reputable vulnerability advisory feeds (e.g., NVD, GitHub Advisory Database, OSV.dev). This automated process quickly identifies known vulnerabilities (CVEs) and malicious package indicators in both newly introduced and existing dependencies, allowing for rapid remediation before deployment.
The security landscape of open-source supply chains in 2025 underscored a critical lesson: passive consumption of public packages is no longer viable. Organizations must implement a layered defense strategy, moving beyond mere vulnerability scanning to embrace architectural controls that inherently distrust external components until their integrity and safety are unequivocally established. The adoption of these compensating controls is not just a recommendation but a necessary paradigm shift for robust cybersecurity in the modern software development era.