A startup with no security team can cut malicious package risk in a day: commit lockfiles, install with frozen lockfiles in CI, turn off install scripts where you can, delay brand-new versions, protect developer credentials with phishing-resistant sign-in, and add one scanner that flags malicious and vulnerable packages on every pull request.
What are you defending against?
CISA's September 2025 alert on the npm ecosystem shows the shape of a modern attack. A self-replicating worm compromised over 500 packages. After it got in, the malware hunted for credentials, including GitHub personal access tokens and cloud API keys. It then used the compromised developer's own npm login to publish infected versions of other packages.
Notice the target. The goal was credentials, not your application. A single poisoned dependency on a laptop or a build runner can hand over the keys to your repositories and your cloud account. That is why a small team's first priorities are limiting what installs run and what secrets are exposed.
Which cheap controls matter most?
Commit your lockfiles and install from them. npm's documentation says npm ci requires an existing lockfile, exits with an error if it does not match package.json, and never writes to the lockfile. Use it in CI so the build installs exactly what was reviewed. CISA's advice in that alert also begins with a dependency review using lockfiles to find affected packages, including nested ones.
Turn off install scripts where you can. The ignore-scripts setting, which defaults to false, stops npm from running scripts in package files. Some packages need their scripts, so test it, then allow exceptions by name instead of leaving everything open.
Delay brand-new versions. A brand-new release has had little time for anyone to notice a problem. GitHub's built-in update tool applies a default three-day cooldown to version updates, though not security updates, and the cooldown is configurable. Whatever tool you use, avoid adopting a release the hour it appears.
Verify what you download. npm audit signatures verifies registry signatures and the provenance attestations of downloaded packages. Provenance shows where and how a package was built. Treat it as a signal, because many packages do not publish it.
Protect the humans. CISA recommends rotating developer credentials after such an event and mandating phishing-resistant multifactor authentication on developer accounts, especially GitHub and npm. Remove GitHub Apps and OAuth apps you do not use, and turn on branch protection and secret scanning alerts.
Keep secrets out of build environments. Give CI jobs the narrowest short-lived credentials possible. If a malicious package runs in a job, it can only take what the job holds.
What should a scanner do for you?
Pick a scanner you will actually look at. It should run on pull requests, flag malicious packages as well as known vulnerabilities, cover transitive dependencies, and say what to do next. Safeguard offers a free in-browser scan of up to 100 dependencies at gold.safeguard.sh/scan, which is a way to try the idea on one repository with no setup. Whatever you pick, trial it on a real repo first.
What are the limits?
Detection lags. A malicious package may be live before any list includes it, and none of these steps makes a compromised dependency harmless. The controls above reduce the chance of installing it, reduce what it can run, and limit what it can steal. They also give you a record of what you installed, which helps when you must answer the question "were we affected?"
What to do
- Commit lockfiles in every repository.
- Switch CI to frozen installs, such as
npm ci. - Try
ignore-scriptsin CI and allow exceptions by name. - Configure a cooldown on automated version updates.
- Require phishing-resistant multifactor authentication on GitHub, your registry and your cloud accounts.
- Review installed GitHub Apps and OAuth apps, and remove unused ones.
- Add a scanner for malicious and vulnerable packages to pull requests.
- Write a one-page runbook: if a dependency is reported compromised, who searches lockfiles, who rotates credentials, in what order.
Quick check
Does a lockfile protect me from a malicious package?
It stops silent changes, so a compromised new version does not enter a frozen install unnoticed. It does not help if the malicious version was already in the lockfile when you committed it.
What is the first thing to do after a compromise report?
Search lockfiles and caches for the affected packages and versions, then rotate credentials that may have been exposed on machines or runners that installed them.
Sources
- CISA, Widespread Supply Chain Compromise Impacting npm Ecosystem
- npm Docs, npm ci
- npm Docs, config (ignore-scripts)
- npm Docs, npm audit (signatures)
- npm Docs, Generating provenance statements
- GitHub Docs, Dependency update configuration options (cooldown)
Last reviewed: 18 October 2026.