A modest proposal
Another week, another npm supply chain attack. Yikes! People on hacker news are wringing their hands about what should be done. The problem seems dire.
Apparently I couldn’t help myself. At 2am the other night I woke up, staring at the ceiling. I couldn’t stop thinking about this problem. It seems .. frankly, solvable. But how?
I think I came up with an answer. Or, the sketch of an answer. Is it any good? Will it work? I think it might… You be the judge.
The problem
The fundamental problem with npm is that any package you install has full access to do whatever it wants on your computer. For example, packages can:
- Read every file on your computer, including your email, passwords, everything.
- Edit your files. Delete them. Cryptolocker them
- Do anything it wants on the internet
- Run child processes, change your OS settings, install key loggers
You think you’re installing leftpad
. But you’re actually letting a stranger into your house while you aren’t at home. They can do basically whatever they want.
And its not just your home. We give package authors full access to our servers and our webpages. These systems store something much more precious: Our users’ personal data.
Most people are trustworthy. But occasionally people decide that if you’re in Russia or Belarus, wiping your hard drive is fair play. And if you let literally thousands of unknown people into your house unattended, its no surprise when someone does something you don’t like. Frankly, I’m surprised supply chain attacks don’t happen more often.
We can’t solve this by figuring out all the baddies and banning them. I learned this as a kid in the 90s playing a video game called Theme Park. Once you played it enough, some park visitors would start vandalizing the park. I remember reading a strategy guide which said “You can’t just hire a security guard and put them at the front gate. Security guards can only kick out visitors after they’ve broken the rules.”
We have the same problem. We can’t preemptively figure out which developers don’t deserve our trust.
Deno tries to solve this problem, but I don’t think its good enough. Deno lets you specify at the command line what kinds of actions your program is allowed to perform. You need to explicitly give permission to your deno process to have access to the internet or your database files.
This is a start; but I don’t think its good enough. Just because I’m making a web server, that doesn’t mean leftpad
should be allowed to access the internet. If I’m making a file server, the leftpad
library shouldn’t have access to my filesystem. Deno’s permission model is a good start, but it just isn’t fine grained enough. (That said, I’d certainly take it over nodejs’s current approach.)
Capabilities to the rescue
I think we can solve this problem entirely. But it might require some changes to how nodejs works.
I’m taking inspiration here from an OpenBSD API called pledge. The way pledge works is that, when the program starts but before your program has done anything, you make a set of pledges. “I promise this program will not access any files outside of /some/path
, or make any network connections to peers except for example.com
. If the program is later compromised, none of the compromised code can do a