Sandboxed NPM

I recently started a new project, and all the anxiety around someone running peacenotwar or other similar malicious code which would simply wipe my computer is coming up again.

Sandboxed NPM

I recently started a new project, and all the anxiety around someone running peacenotwar or other similar malicious code which would simply wipe my computer is coming up again.

In a modern world, we have to realise that we as developers are a target group too, and we have to take precautions to prevent becoming victims of malware.

A Note On History

A while back, the maintainer of node-ipc decided that it was the developers in Russia's fault that their leader decided to invade another country, and that maintainer also decided that the proper cause of action was to wipe the computers of said developers who just happened to live in Russia, to make some kind of statement.

This is far from the only instance of npm packages containing malicious code, but it is fairly recent, and particularly destructive.

At the time, I was using Vue for my personal website, and I was quite scared that by this. It hit a little too close to home for me. I immediately ported my website from Vue to React (which was also a learning experience - in how easy porting can be if you did some simple things right to begin with - which ended up being a good thing).

But my faith in humanity was definitely shaken.

Vue is widely used and trusted, worldwide, and still this happened.

Existing Options

So I asked myself, which options exist out there to prevent something like this from happening again at some point in the future.

There is no feasible way I can review the thousands of dependencies of the larger frameworks for malicious code any time I run npm update.

I can definitely start using devcontainers whenever I run my code. It's a fairly easy fix, since I'm using VS Code anyway.

But what about the installation step?

What if I just want to quickly run a service/app to test it or integrate it with something else?

What if I don't want to use VS Code because I'm doing something quick'n'dirty?

What if I want to share a solution with those crazy people who use vim for everything?

Dockerize All The Things

As usual, the solution to most things is containerization. That is true in this instance, too.

It is totally possible to simply spin up a temporary docker container just to run npm install - it's just a bit of a mouthful:

This will work.

It will even work if you have any private module dependencies which require you to have authentication tokens in your $HOME/.npmrc.

You will end up with a node_modules folder with installed dependencies, and any post-installation scripts will have run, and you are completely ready to go.

If there were any evil system-wiping scripts running in a post-install step then they would just have wiped the temporary docker container which would have been deleted at the end of the installation anyway (see the --rm parameter).

There is a caveat, of course. If any of the dependencies need a compilation step, then node:18-bullseye doesn't dome with make or gcc preinstalled, so we need to take care of that.

This brings us to the next caveat:

This will only work if you host system is compatible with Debian-bullseye binaries, so you are out of luck if you are running on a Mac (like every single software engineer I have met since circa 2010 does).

Even if you are running a Debian-bullseye system, what is stopping the malware from also doing something bad after the installation step - at runtime?

At this point, you want to run everything node-related in a container. E.g. starting a service listening on port 3000 would look like this:

Perspectives

What this probably looks like going forward, is that I could alias my way out of most of this, but in reality, I will probably just start using devcontainer for everything.

This is why we need a 12-core CPU and 96GiB RAM to write some HTML for a website.


There is a thread on mastodon about this post.

Mastodon