Member preview

The Node.js Ecosystem Is Chaotic and Insecure

A modern web developer at work

It seems like only yesterday we had the “left-pad” fiasco where Azer Koçulu ended up pulling his packages after a name dispute.

It wasn’t really that dangerous that the code was deleted, that only broke the builds which everyone noticed during their build process and the whole ordeal lasted for like two hours.

It was dangerous because that it was a small redundant package that no one would ever actually bother to audit before deploying, so anyone could have jumped in and published a package in it’s place with the same functionality but also stick some malicious code into it and get a free ride to get deployed essentially anywhere that ran JavaScript.

Well, it sure is a good thing we learned our lesson from that isn’t it?

We Still Can’t Code

When left-pad hit, developers from other camps were having their laughs at how this tiny piece of code could be a module. Good thing we have learned by now right? Well, no, not at all.

The following wonder of engineering aptly named is-odd has around 500 000 downloads per day.

Going through the dependents tree, I found hundreds of projects depending on this but more importantly also the big players including Webpack, BrowserSync and Babel depend on it.

Basically this means that if this package was a trojan waiting to do a bait-and-switch in a minor patch then it could theoretically inject code into the developer’s machine but also inject itself into the code generation of whatever prepreprocessors available via require, including Babel and Webpack.

Now that’s a lot of power to give to a package that should just have been a single modulus or bitwise operator call.

But surely this is a freak occurrence right? Actually no, it’s common practice today, the “do not repeat yourself” mantra has been taken a bit too literally where many will consider even writing basic one liners re-inventing the wheel.

The is-number package has nearly two million downloads per day. is-odddepends on this package.

My personal favorite is the is-even package, because using the negation operator is also reinventing the wheel?

var isOdd = require('is-odd');
module.exports = function isEven(i) {
return !isOdd(i);
};

Now, to be fair to the author and maintainers of the glorious packages mentioned earlier the problem applies to all packages in the package repository. There are thousands of similarly trivial packages from hundreds of both known and completely unknown anonymous authors which are just as popular with millions of downloads per week and indirectly depended upon by many of the popular projects.

Be Responsible

It’s simple; don’t trust package managers, every dependency is written by some random developer somewhere in the world and is a potential attack vector. This applies to all package managers but these one liner packages makes it so that no effort is required.

All it takes is for one single maintainer to wait until the reach is wide enough, then release a patch with a malicious payload and it spreads like wildfire because no one actually looks at and locks down a dependency like is-string to a patch version.

Is this being too paranoid? Perhaps, or maybe it’s the healthy amount considering the massive reach these trivial packages can have.

There has already been a bunch of browser extensions that have been injected with a cryptocurrency miner using the same bait and switch strategy, and those are supposedly reviewed by humans.

There’s no lack of smart people out there trying to spread their malware, which begs the question why would anyone looking to do something malicious bother with all the work involved in finding cross-site scripting exploits when you can just create a rubbish package with zero effort, release it and just let the developers spread it around.

At this point it seems fairly probable that in a best case scenario a few cryptocurrency miners are currently living in the npm package repository already running on developers machines, servers and even on client’s machines through the Web and Electron applications. It could also be worse, with actual nefarious malware mining sensitive data.

TL;DR

  • Node modules are widespread and ripe for abuse.
  • Nonsense dependencies are hard if not near impossible to manually audit due to the sheer number of them.
  • Manually audit and lock down your dependencies.
  • Stop using nonsense dependencies, writing basic code is not reinventing the wheel.