Skip to content

npm

The JavaScript package registry behind Node.js apps and many web front ends.

  • Registries

About

npm is the public registry for JavaScript packages, and the tool that installs them. A Node.js app names the packages it needs, and those often pull in hundreds more of their own. Each one is code from outside the team, fetched whenever the app is built.

A package can carry install scripts, commands that run the moment it is installed, with the rights of whoever installs it, on a laptop or a build server. The rest of its code runs inside the app at every start, or in visitors' browsers when it is bundled into the front end.

If It Is Malicious

If an npm package is malicious, it runs inside a Node.js app with the app's rights, on every developer laptop and build server that installs it.

Its code runs inside these technologies.

See It in the Stack

Examples

These are well-known names from npm, written as you would meet them in an inventory, an alert or a lockfile, the file that records every version a build installed.

express
The web framework many Node.js apps are built on.
react
The library many web front ends are built with.
lodash
Utility functions found in a great many Node.js apps.
chalk
Colours text in the terminal. It was hijacked in September 2025.
debug
A small logging helper that thousands of packages depend on.

How Bad Code Gets In

These are the ways bad code can reach your systems through npm. None of them needs a flaw in your own code, so outside code needs checking as much as your own.

  • A maintainer's account or publishing token is stolen, and a bad version goes out under the real name.
  • A new maintainer, given control of a popular package, adds hidden code, sometimes through a new dependency.
  • A maintainer sabotages their own package on purpose, to make a point.
  • A package named like a popular one catches mistyped installs.
  • A public package with the same name as an internal one is installed in its place.
  • A worm uses the tokens it steals to publish infected versions of more packages.

How to Check

These checks show what came from npm, whether a known bad version is in use, and how to keep one out next time.

  • Commit package-lock.json and install with npm ci, so every build gets exactly the reviewed versions.
  • Run npm audit, or match the lockfile against OSV and GitHub advisories, in every build.
  • When an incident breaks, search every lockfile and image for the named versions.
  • Install through a private registry or proxy that can hold back brand-new versions.
  • Turn off install scripts where a build does not need them, with npm's ignore-scripts setting.
  • Check registry signatures and provenance with npm audit signatures.

Well-Known Incidents

Each incident below is a real case, told at the level of its public advisory. The tag says how the bad code got in, and the link opens the primary source.

  • Malicious Update2018

    event-stream Takeover

    A stranger offered to maintain a popular stream library, was given control of it, and added a new dependency carrying hidden code aimed at one bitcoin wallet app.

    Reach The library was widely used, but the code only woke inside the release build of the Copay wallet app. Copay shipped it to users, set to steal the keys of wallets holding large balances.

    Affectedevent-streamflatmap-stream

    Source: blog.npmjs.org (opens in a new tab)
  • Dependency Confusion2021

    Dependency Confusion Research

    A researcher showed that the build tools of many large companies would fetch a public package in place of an internal one with the same name.

    Reach His test packages, which only reported back, ran inside more than 35 organisations through npm, PyPI and RubyGems. Apple, Microsoft and PayPal were among them.

    Source: medium.com (opens in a new tab)
  • Hijacked Account2021

    ua-parser-js Hijack

    Attackers took over the maintainer's npm account and published three versions that installed a cryptominer and, on Windows, a password stealer.

    Reach Many other libraries depend on it, so laptops and build servers that installed a bad version ran the malware. Every password, key and token on them had to be changed.

    Affectedua-parser-js

    Source: cert.europa.eu (opens in a new tab)
  • Protestware2022

    Two Libraries Sabotaged by Their Author

    Saying he would no longer work for free, the author of two popular libraries released versions that broke them on purpose. One printed endless garbage, and the other was emptied.

    Reach Apps and tools that took new versions automatically broke at once, Amazon's AWS Cloud Development Kit among them.

    Affectedcolorsfaker

    Source: snyk.io (opens in a new tab)
  • ProtestwareCVE-2022-238122022

    node-ipc Protestware

    Its maintainer added code that overwrote files on machines whose IP address placed them in Russia or Belarus, then a module that left a protest message on the desktop.

    Reach Developers got it through tools that depended on it. Vue CLI pulled in the version with the desktop message, though its users never chose node-ipc.

    Affectednode-ipcpeacenotwar

    Source: snyk.io (opens in a new tab)
  • Hijacked Account2025

    The chalk and debug Takeover

    Attackers took over a maintainer's account with a phishing email from a fake npm support address, and bad versions of chalk, debug and other basic packages went out.

    Reach Together they are downloaded billions of times a week. The code targeted cryptocurrency payments in web pages that bundled it, and most bad versions were removed the same day.

    Affectedchalkdebugansi-stylesstrip-ansisupports-colorwrap-ansi

    Source: aikido.dev (opens in a new tab)
  • Hijacked Account2025

    Shai-Hulud Worm

    A worm spread through npm by itself. Each infected package took the installer's tokens and secrets, posted them to public GitHub repositories, and used them to infect more packages.

    Reach Hundreds of packages were infected, some published by a security vendor, and a larger second wave followed in November 2025.

    Affected@ctrl/tinycolor

    Source: cisa.gov (opens in a new tab)

In Common Stacks

These common stacks take code from npm. Open one to see where that code sits among its layers and who runs each one.

Sources

Product names and logos are trademarks of their owners, shown only to name each product, with no endorsement implied. npm is a registered trademark of npm, Inc.

Apache, Apache HTTP Server, Tomcat and Log4j are trademarks of the Apache Software Foundation. Node.js® is a registered trademark of the OpenJS Foundation, and Kubernetes® of LF Projects, LLC.

Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries. Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.

MongoDB® is a registered trademark of MongoDB, Inc. Redis® is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd.

PHP logo by Colin Viebrock, CC BY-SA 4.0 (opens in a new tab). Ruby logo © 2006 Yukihiro Matsumoto, CC BY-SA 2.5 (opens in a new tab). Tux by Larry Ewing, with Garrett LeSage and IFo Hancroft.

Puma logo © Evan Phoenix and contributors, CC BY-ND 3.0 (opens in a new tab). NuGet logo from NuGet's Media repository, CC BY 2.0 (opens in a new tab).

Gunicorn logo © Benoît Chesneau and Paul J. Davis, MIT licence for the Gunicorn logo (opens in a new tab). Packagist logo © 2011 Jordi Boggiano and Nils Adermann, MIT licence for the Packagist logo (opens in a new tab).

MIT Licence Notices for the Gunicorn and Packagist Logos

Gunicorn logo

2009-2024 (c) Benoît Chesneau <benoitc@gunicorn.org> 2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Packagist logo

Copyright (c) 2011 Jordi Boggiano, Nils Adermann

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.