SuperGeekery: A blog probably of interest only to nerds by John F Morton.

A blog prob­a­bly of inter­est only to nerds by John F Mor­ton.

npm in a box: Containerizing package managers for security.

npm in a box

I’ve writ­ten about Dock­er quite a bit recent­ly. This flur­ry of activ­i­ty about Dock­er is direct­ly relat­ed to a post by Andrew Welch, Dock Life: Using Dock­er for All The Things! He describes how to use alias­es and Dock­er con­tain­ers to run apps typ­i­cal­ly installed on a developer’s com­put­er with­out need­ing to install soft­ware direct­ly on the machine.

I have whole­heart­ed­ly embraced the method­ol­o­gy. The idea of run­ning devel­op­ment tools in Dock­er con­tain­ers for basic util­i­ties coin­cid­ed with the arrival of my new com­put­er, a Mac­Book Pro. Although I rely on Node.js, npm (frus­trat­ing­ly, not cap­i­tal­ized), and a bunch of oth­er devel­op­ment tools, I have not installed any of them on my lap­top and can still use them every day with­out issue. I haven’t even installed Home­brew, the miss­ing pack­age man­ag­er for macOS (or Lin­ux),” a tool Mac users typ­i­cal­ly rely on to install var­i­ous soft­ware.

Andrew men­tions many ben­e­fits of this approach. I won’t restate them here. This post is pri­mar­i­ly about an addi­tion­al ben­e­fit: secur­ing your com­put­er.

Are shared resources a problem?

The shared-resources ecosys­tem we cur­rent­ly rely on is incred­i­bly use­ful. We can include a well-writ­ten library into a project with a few com­mands. For exam­ple, I wouldn’t want to write an ajax library every time an app need­ed to talk to an API. I just use Axios and move to the next task at hand.

There are a vari­ety of shared ecosys­tems. I reg­u­lar­ly rely on 2 of them, com­pos­er for PHP pack­ages and npm for Javascript pack­ages. Although I’ll frame this arti­cle with ref­er­ences to the secu­ri­ty of npm, since it is famil­iar to me, the secu­ri­ty ben­e­fits of con­tainer­iza­tion can be applied broad­ly.


A closer look at npm

I think npm is a fan­tas­tic resource, but I believe it is even bet­ter when used inside a Dock­er con­tain­er. Let’s out­line why this is the case.

Pop­u­lar­i­ty pro­vides a wide attack sur­face for mal­ware to make an impact and npm is very pop­u­lar. At the time I write this, March 30, 2022, the npm home­page reports that there were 42,843,361,218 down­loads from npm last week.


npm homepage showing usage as of March 30, 2022

npm homepage showing usage as of March 30, 2022


That’s a sig­nif­i­cant attack sur­face. Report­ing sug­gests that npm is a play­ground for mali­cious actors.”

JavaScript is the most com­mon­ly used pro­gram­ming lan­guage glob­al­ly, and 68% of devel­op­ers depend upon it to cre­ate rich online func­tion­al­i­ty. With an aver­age of 32,000 new npm pack­ages pub­lished per month in 2021, attack­ers are using the pop­u­lar­i­ty of npm to hide their nefar­i­ous behav­ior and launch attacks. In just six months, more than 1,300 mali­cious npm pack­ages have been iden­ti­fied and report­ed by White­Source Dif­f­end, mak­ing it vital for devel­op­ers to under­stand what attack­ers are doing and how they can reme­di­ate issues with­out slow­ing down the devel­op­ment process.

That sounds pret­ty scary. We can look beyond white papers and for some real-life exam­ples.

This is just a frac­tion of news arti­cles on the top­ic. npm and oth­er pack­age man­agers present fer­tile ground for peo­ple wish­ing to bad things at scale. Why? Because it’s built on trust and there are some untrust­wor­thy char­ac­ters, even if they are small in num­ber.

Fear not! Ok, maybe, just fear somewhat.

npm is aware of the prob­lem and already has plans for deal­ing with secu­ri­ty threats. A sec­tion of their site is ded­i­cat­ed to secur­ing the ecosys­tem. There is an audit­ing process in npm and a process for report­ing mal­ware. They like­ly have oth­er non-pub­lic plans in place as well.

The npm secu­ri­ty process­es help fix prob­lems on a net­work lev­el. If a pack­age is com­pro­mised and makes its way into the glob­al reg­istry, npm can pull the pack­age from the reg­istry when it becomes known. It can also warn you in the com­mand line of dis­cov­ered vul­ner­a­bil­i­ties in the pack­ages you use. Github has Depend­abot alerts to also help you iden­ti­fy these prob­lems and cor­rect them. These are good efforts but they deal with prob­lems after they’re dis­cov­ered.


Use Docker to protect your local machine

There is still the pos­si­bil­i­ty that you will install a mali­cious piece of code before a threat has been iden­ti­fied. You can use Dock­er to help con­tain prob­lems.

Let’s imag­ine a sce­nario sim­i­lar to the one men­tioned in the Sab­o­tage link above.

A devel­op­er has been caught adding mali­cious code to a pop­u­lar open-source pack­age that wiped files on com­put­ers locat­ed in Rus­sia and Belarus as part of a protest that has enraged many users and raised con­cerns about the safe­ty of free and open source soft­ware.

Instead of delet­ing files on com­put­ers locat­ed in Rus­sia and Belarus” in this imag­i­nary sce­nario, mali­cious code eras­es 20 ran­dom files it comes across. The files at risk are any­where that npm can access.

Scenario #1: Global installation of your dev tools

You’re encour­aged to run your dev tools on your machine glob­al­ly. Why are you doing this?

Look at the Down­load­ing and installing Node.js and npm guide. How do you install npm? There’s a sim­ple com­mand for that.

npm install -g npm

What about upgrad­ing an instal­la­tion of npm? Anoth­er sim­ple com­mand. Handy! (BTW, I’m encour­ag­ing you to not to do this! Don’t con­sid­er this sec­tion as instruc­tion on what to do.)

npm install npm@latest -g

What does -g mean in each of those com­mands? Glob­al.

The doc­u­men­ta­tion active­ly encour­ages you to do glob­al instal­la­tion of your tools so, in our first sce­nario, that’s what you’ve done. You fol­lowed instruc­tions. Since this is the nor­mal way of doing things, your dev serv­er may also be run­ning glob­al­ly on your machine. This glob­al con­text is what our the­o­ret­i­cal mali­cious pack­age will use at its attack sur­face, ran­dom­ly delet­ing files it finds. Your entire com­put­er is open for exploita­tion.

You’ve installed the mali­cious pack­age from npm and now 20 ran­dom files on your com­put­er are sim­ply gone. It’s easy to imag­ine the hav­oc the code could cause.

Scenario #2: Dev tools installed in a container

If you’re run­ning your devel­op­ment tools as Andrew sug­gest­ed in Dock Life: Using Dock­er for All The Things! you are in a much bet­ter posi­tion in my opin­ion. Files in the project you’re work­ing on still are poten­tial­ly vul­ner­a­ble.

This is still a bad sit­u­a­tion. The files in your project face poten­tial dele­tion or alter­ation. You could lose 20 files in your project when the mal­ware attacks.

Since this is a devel­op­ment project, all of these files are like­ly under source con­trol. You will have a remote git repos­i­to­ry that con­tains the com­plete his­to­ry of this project before the infec­tion.

Since you’re run­ning your dev tools in Dock­er con­tain­ers, you can shut them down and destroy them. You can pull down fresh copies of the last work­ing ver­sion of your code from your git repo and pick up from the point the mali­cious code was installed.

Security issues still remain

Using Dock­er con­tain­ers for your dev tools does not solve the glob­al shared resource pool prob­lem. There are still many ways things can go wrong, but using your tools in con­tain­ers can lim­it the poten­tial dam­age you face.


Tradeoffs

Before I wrap this up, we should talk about the down­sides.

Public reaction? Mixed.

If you read through the com­ments post­ed at the end of Andrew’s arti­cle, you’ll see the com­ments post­ed are mixed as best. I’ll sum­ma­rize the com­ments in a pos­i­tive way:

It’s not the same as installing depen­den­cies glob­al­ly and there are trade­offs some­times in not hav­ing apps run­ning glob­al­ly on your sys­tem.

As I men­tioned at the begin­ning, I use my dev tools in con­tain­ers with­out issue, but it does require some changes in your behav­ior. I am used to the work­flow, but I think it requires under­stand­ing how con­tain­ers work.

If you’re inter­est­ed in try­ing this out with­out div­ing ful­ly into the deep end, check out my post Mak­ing a Basic Dock­er Image. At the end of that post, you will have a sin­gle con­tained” com­mand-line tool, tree not installed on your com­put­er but still usable on your com­put­er. Also be sure to read Dock Life: Using Dock­er for All The Things!.

Good luck. If you have thoughts, please feel free to reach me on Twit­ter, @johnmorton.