On March 20, 2026, the CanisterWorm attack hit npm. A malicious package slipped into thousands of projects by mimicking a trusted name. It sat quietly in node_modules, doing nothing visible — until it did.
I saw the headlines. I closed the tab. My projects are fine, I thought.
Then I actually checked.
What the CanisterWorm Attack Was
CanisterWorm was a supply chain attack targeting the npm ecosystem. The attacker published packages with names visually similar to popular ones — a technique called typosquatting. Developers who ran npm install with a small typo (or whose dependencies pulled in a look-alike transitively) ended up with malicious code on their machines.
The attack exposed something many of us already knew but ignored: we have no idea what's actually in our node_modules. Not the sizes. Not the security status. Not how long it's been since anyone looked at the code.
I Ran node-weight on My Own Project
After reading about CanisterWorm, I ran node-weight on one of my own Node.js projects. Zero install needed:
npx node-weight
Here's what came back (trimmed for brevity):
┌───────────────────────────┬───────────┬──────────┬───────────────┐
│ Package │ Size │ Security │ Last Updated │
├───────────────────────────┼───────────┼──────────┼───────────────┤
│ zod │ 4.1 MB │ ✓ clean │ 70 days ago │
├───────────────────────────┼───────────┼──────────┼───────────────┤
│ @modelcontextprotocol/sdk │ 4.1 MB │ ✓ clean │ 37 days ago │
├───────────────────────────┼───────────┼──────────┼───────────────┤
│ path-to-regexp │ 55.0 KB │ ● HIGH │ 212 days ago │
├───────────────────────────┼───────────┼──────────┼───────────────┤
│ safer-buffer │ 41.3 KB │ ✓ clean │ 2916 days ago │
├───────────────────────────┼───────────┼──────────┼───────────────┤
│ depd │ 26.5 KB │ ✓ clean │ 2715 days ago │
├───────────────────────────┼───────────┼──────────┼───────────────┤
│ argparse │ 167.5 KB │ ✓ clean │ 2043 days ago │
└───────────────────────────┴───────────┴──────────┴───────────────┘
What the Numbers Actually Mean
path-to-regexp flagged HIGH — this is a real, confirmed vulnerability. path-to-regexp is a routing utility used by Express.js. The HIGH flag means npm audit knows about it. If you're running Express with user-controlled routes and haven't updated this, you're exposed.
safer-buffer — 2,916 days since last update. That's over 8 years. It's a polyfill for the Node.js Buffer API that was relevant during the Node 4→6 migration. Your project almost certainly doesn't need it anymore — it's a transitive dependency of something ancient in your chain.
argparse — 2,043 days. About 5.5 years. Also a transitive dep, likely from a dev tool. Not dangerous on its own, but a package that hasn't been touched in half a decade is unlikely to be actively maintained if a vulnerability surfaces.
The 4 MB packages — zod and @modelcontextprotocol/sdk are both huge. Neither is a security risk here (both marked clean), but seeing the size surfaced makes me ask: do I need both versions? Is there a lighter alternative? Size awareness matters for Lambda functions, Docker images, and CI build times.
General rule of thumb:
-
● HIGHor● CRITICAL→ fix now. Runnpm audit fix. - 500+ days since last update, transitive dep → probably safe to ignore, but note it.
- 2,000+ days → worth checking if the dep is even necessary anymore.
- Large size + "clean" → no security issue, but worth knowing for optimization.
The Actual Lesson From CanisterWorm
The attack wasn't primarily technical. It was about familiarity blindness — we trust packages because we've seen the name before. We don't look at when they were last updated, how big they are, or whether they have open CVEs.
node-weight doesn't prevent supply chain attacks. But running it gives you a map of your dependencies that you can actually reason about. When you can see that a package is 8 years old and 40 KB, you start asking: does my project actually need this? That question is the beginning of a better security posture.
Run it on your project:
npx node-weight
No install. Scans your node_modules in seconds.
Top comments (0)