npm Supply Chain Attacks
Updated 5 Oct 2026
An npm supply chain attack puts malicious code into a package that developers already trust. This page lists recent attacks, explains how the malware gets in, and shows how to check an update before you install it.
What an npm supply chain attack is
An npm supply chain attack is a malicious change to a package that developers already trust. The attacker publishes a new version of the real package, and normal installs pull it in.
The attacker usually does not write a new package. The attacker takes over a real one. Socket reports that a maintainer received a phishing email that spoofed npm and warned of outdated 2FA credentials. The attacker then published malicious versions of chalk, debug and other packages on 8 September 2025. Read our record of that attack.
The rest of the new version is the software that people asked for. The change is often one file or one line. That makes a list of changed files a weak signal. The question that matters is what the new file can do.
Recent npm attacks
The Vigilance attack library holds 24 npm records, from 2018 to September 2026. Each link opens a page with the package, the version change and the capability that the update gained.
- @apexacc/cli Defender-blinding C2 loader, 17 Sep 2026
- keyv and cacheable npm worm (Shai-Hulud third wave), 4 Aug 2026
- Mastra AI npm compromise (Sapphire Sleet), 17 Jun 2026
- TanStack npm compromise (Mini Shai-Hulud), 11 May 2026
- axios npm maintainer account takeover, 31 Mar 2026
- Shai-Hulud 2.0 (second wave), 24 Nov 2025
- chalk, debug and ansi-styles maintainer phishing compromise, 8 Sep 2025
- Nx s1ngularity compromise, 26 Aug 2025
- eslint-config-prettier and eslint-plugin-prettier phishing compromise, 18 Jul 2025
- gluestack and react-native-aria compromise, 6 Jun 2025
- rand-user-agent RAT compromise, 5 May 2025
- xrpl.js (XRP Ledger SDK) backdoor, 21 Apr 2025
- Rspack and Vant npm token compromise, 19 Dec 2024
- LottieFiles lottie-player compromise, 30 Oct 2024
- Ledger Connect Kit wallet drainer, 14 Dec 2023
- rc npm library hijack, 4 Nov 2021
- coa npm library hijack, 4 Nov 2021
- ua-parser-js account hijack, 22 Oct 2021
- PureScript npm installer sabotage, 5 Jul 2019
- electron-native-notify and Komodo Agama wallet attack, 23 Mar 2019
- event-stream and flatmap-stream backdoor, 9 Sep 2018
- eslint-scope and eslint-config-eslint credential theft, 12 Jul 2018
- getcookies backdoor shipped through mailparser, 12 Apr 2018
- conventional-changelog crypto-miner publish, 12 Feb 2018
Five of them show the range of methods:
- axios, 31 March 2026. Huntress reports that an attacker used a long-lived access token to publish axios 1.14.1 and 0.30.4 directly. This skipped the normal GitHub Actions publishing workflow. The new versions added a dependency, plain-crypto-js, with a postinstall hook that deployed remote access trojans. See the axios page and the short axios record.
- Shai-Hulud 2.0, 24 November 2025. Datadog reports that the worm hit 796 unique packages. A new preinstall script installed the Bun runtime and harvested credentials. The worm used stolen npm credentials to backdoor more packages. See the Shai-Hulud 2.0 page.
- Nx s1ngularity, 26 August 2025. StepSecurity reports eight malicious versions that stayed live for about five hours. A postinstall script read GitHub tokens, npm credentials and SSH keys. See the Nx page.
- TanStack, 11 May 2026. The TanStack postmortem reports 84 malicious versions across 42 packages. They went out in six minutes through a trusted publisher binding. See the TanStack page.
- event-stream, 2018. Snyk reports that an attacker earned the maintainer's trust and received publishing rights. The payload targeted the Copay bitcoin wallet build. See the event-stream page.
The full attack library also holds PyPI, crates.io, vendor installer and other records.
How malware gets into npm packages
Malware reaches an npm package in four main ways. The records above show each one.
- A stolen maintainer account. Phishing took the chalk and debug maintainer account. A hijacked account published the ua-parser-js versions that the GitHub advisory lists as 0.7.29, 0.8.0 and 1.0.0.
- A stolen publish token. The Nx attack used a token that a flawed GitHub workflow exposed. The axios attack used a long-lived token.
- A weak build pipeline. The TanStack attack combined a pull_request_target workflow flaw, cache poisoning and a token pulled from runner memory.
- A new dependency. The attacker adds a small package that holds the payload. The axios and event-stream cases both worked this way.
Install scripts carry many of these payloads. The axios, Shai-Hulud 2.0 and Nx attacks all used a postinstall or preinstall script. The script runs on the machine of whoever installs the package. That machine is often a developer laptop or a build server with many secrets.
A malicious version can also spread itself. The Shai-Hulud 2.0 worm used stolen npm credentials to backdoor more packages that its victims owned.
How to protect yourself
Protect yourself by limiting what an install can run, limiting who can publish, and checking what each update can do. Use these steps.
- Set
ignore-scriptsto true where you do not need install scripts. The npm documentation says npm then does not run scripts that package.json lists. The default is false. - Pin versions with a lockfile and read each update before you accept it.
- If you publish packages, move to trusted publishing. It replaces long-lived write tokens with short-lived credentials from your workflow.
- Run an SCA or malware detection tool on the packages your developers pull. See software supply chain security tools.
- Compare the version you trust with the new one. Vigilance reports the file that gained a new capability, such as a new install script or a network call. Run
vigi diff --old ./current --new ./update.
A new capability needs review. It does not prove that an update is malicious. Vigilance reports what it finds, and your team decides what to install. The nine prevention controls cover the rest of the pipeline.
npm and PyPI compared
Both registries have had the same kind of attack: a trusted package gets a malicious new version. The method of running the payload differs.
BleepingComputer reports that litellm 1.82.7 and 1.82.8 reached PyPI on 24 March 2026. Version 1.82.7 hid a base64 payload in a Python module that ran when the module loaded. Version 1.82.8 added a .pth file, which Python processes when the interpreter starts. The payload then ran even if no code imported litellm. See the litellm page.
An npm payload more often rides on an install script. A PyPI payload can ride on a module import or a .pth file. Both registries support trusted publishing. PyPI documents it as an OIDC exchange of short-lived tokens, and so does npm.
The protection is the same in both. Pin versions, avoid long-lived publish tokens, and read what each update changes.
FAQ
What are npm vulnerabilities?
An npm vulnerability is a flaw in a package that an attacker can use, such as a known bug. A malicious version is a different problem. The package works as before and also carries code the attacker added. A CVE scanner finds the first kind. A check of what an update can do finds the second kind. See the attack library.
Check your next update.
Vigilance compares the version you trust with a new one. Download Vigilance to scan your own files.