Compromised npm Package? What to Do
- Time since install (hours)
- 24 h
- You entered
- Number of packages installed
- 150
- You entered
If you installed a compromised npm package, immediately revoke all credentials and secrets that may have been exposed, audit your lockfile and dependencies for malicious code, and rotate any tokens or keys that were present in the environment where the package ran. Then, remove the affected package, update to a patched version if one exists, and scan your project and system for signs of further compromise.
Understanding How npm Packages Get Compromised
npm is the default package manager for Node.js, and it hosts over two million packages. Supply-chain attacks happen when a legitimate package is hijacked or a malicious package is published under a similar name (typosquatting). Attackers may gain access to a maintainer’s account, publish a malicious version, or use a dependency that is itself compromised. Once installed, the malicious code can run during installation (via preinstall scripts) or when the package is required in your application. It can steal environment variables, read files, send data to remote servers, or install backdoors.
Recent high-profile incidents include the event-stream compromise in 2018, where a malicious dependency was added to steal Bitcoin wallets, and the ua-parser-js attack in 2021 that installed cryptocurrency miners. These examples show that even popular, widely-used packages can be affected, and the impact can be severe.
Immediate Steps to Take After Discovery
Time is critical. The longer a compromised package runs, the more data can be exfiltrated. Follow these steps in order:
- Disconnect the affected machine from the network – This stops data exfiltration and remote control.
- Rotate all credentials – Change passwords, API keys, tokens, and any secrets that were in environment variables or config files. Do this from a clean, trusted device.
- Identify the compromised package – Check your
package-lock.jsonoryarn.lockfor the package name and version. Usenpm auditornpm lsto see the dependency tree. - Remove the package – Run
npm uninstall <package-name>or delete it frompackage.jsonand runnpm installto update the lockfile. - Update to a patched version – If the maintainer has released a fix, upgrade to that version. Otherwise, consider replacing the package with an alternative.
- Scan your system – Use antivirus and malware scanners, and check for unusual processes, network connections, or files.
Auditing Your Project for Malicious Code
After removing the obvious package, you need to check for any traces it left behind. The malicious code might have modified other files, added new dependencies, or created scheduled tasks. Here’s how to audit:
- Review your
package-lock.jsonfor any unexpected packages or versions. - Search your project for suspicious code patterns, such as
eval(),child_process,fs.writeFileto unusual paths, or hardcoded IP addresses. - Check your
~/.npmrcfile for altered registry URLs or authentication tokens. - Look for new files in your home directory,
/tmp, or startup folders. - Use tools like
npm auditto identify known vulnerabilities, but remember that zero-day compromises may not be in the database yet.
If you find malicious code, isolate the affected files and preserve them for analysis. You can report the package to npm’s security team via npm report or the GitHub repository.
How to Choose Safe npm Packages in the Future
Prevention is better than reaction. When evaluating a package, consider these factors:
- Popularity – Packages with more weekly downloads are more likely to be reviewed, but they are also bigger targets.
- Maintenance – Check the last publish date and the number of open issues. A package with no recent updates may be abandoned.
- Author reputation – Look at the author’s profile and their other packages.
- Dependencies – Fewer dependencies mean a smaller attack surface.
- License – Ensure it’s a license your project can use.
- Code quality – Read the source code for anything suspicious, especially in the
scriptssection ofpackage.json.
Also, use npm audit regularly, enable two-factor authentication on your npm account, and consider using a private registry or a lockfile with integrity hashes.
Common Mistakes and Misconceptions
One common mistake is assuming that only direct dependencies are risky. Transitive dependencies (dependencies of dependencies) can also be compromised, and they are often overlooked. Another misconception is that installing a package from the official registry is always safe – the registry itself can be tricked into hosting malicious packages, as seen in typosquatting attacks.
People also forget to rotate credentials that were used in the same environment, even if they weren’t directly in the package’s code. Any secret that could have been read by the process is at risk. Finally, some developers only remove the package and don’t audit for changes, leaving backdoors that persist.
Long-Term Security Practices
To minimize the impact of any future compromise, adopt these practices:
- Use a lockfile (
package-lock.json) and commit it to your repository. - Run
npm ciinstead ofnpm installin CI/CD pipelines to ensure exact versions. - Set
ignore-scriptstotruein your.npmrcto prevent install scripts from running, but note that some packages require scripts to work. - Use a vulnerability scanner like Snyk or GitHub’s Dependabot.
- Keep your Node.js and npm versions up to date.
- Limit the use of environment variables with secrets, and use a secrets manager.
- Regularly review your dependencies and remove unused ones.
Frequently Asked Questions
How do I know if my npm package is compromised?
Signs include unexpected network traffic, new files appearing, or the package sending data to an unknown server. You can check the package’s homepage or GitHub repo for security advisories, and run npm audit to see known vulnerabilities. However, zero-day attacks may not be listed, so trust your instincts if something seems off.
Can I get malware from an npm package?
Yes, npm packages can contain malware, especially if they have install scripts that execute arbitrary code. Always review the scripts field in package.json before installing, and consider using npm install --ignore-scripts if you don’t need them.
What should I do if I already ran the package?
Assume your secrets are compromised. Rotate all tokens, passwords, and keys immediately. Then follow the audit steps above to check for persistence mechanisms. If you’re on a work machine, notify your security team.
Is it safe to use npm packages from the official registry?
Most are safe, but the registry is not immune to malicious uploads. Always check the package’s popularity, maintainers, and code before using it. Use npm audit and keep your dependencies up to date.
How do I report a compromised npm package?
You can report it to npm’s security team by emailing security@npmjs.com or using the npm report command. Include the package name, version, and any evidence of malicious behavior. You can also file an issue on the package’s GitHub repository if it’s public.
What is the difference between a vulnerability and a compromise?
A vulnerability is a flaw in the code that could be exploited, while a compromise means the package has been actively modified to contain malicious code. Vulnerabilities are often patched, but a compromised package may not have a fix – you may need to replace it entirely.
Related
Formula used
in t | Time since install (hours) | h | 24 | 0 in c | Number of packages installed | - | 150 | 1 out risk | Estimated exposure score (0-100) | - | min(100, (t / 24) * 50 + (c / 100) * 50) | 0
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.