DEV Community

Profiterole
Profiterole

Posted on

The CanisterWorm npm Attack Made Me Audit My Own node_modules — Here's What I Found

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
Enter fullscreen mode Exit fullscreen mode

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 │
└───────────────────────────┴───────────┴──────────┴───────────────┘
Enter fullscreen mode Exit fullscreen mode

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 packageszod 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:

  • ● HIGH or ● CRITICAL → fix now. Run npm 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
Enter fullscreen mode Exit fullscreen mode

No install. Scans your node_modules in seconds.

npm package · landing page

Top comments (0)