Hacker News new | ask | show | jobs
by pfooti 3237 days ago
I'm working on a node-based REST endpoint. It's nothing special - it looks up stuff in the database, does CRUD things, pokes postgres, has a cache layer in redis, a websocket for handling sidechannel stuff like model update events for realtime data updates and so on. It has 514 dependencies in total. It's actually only 39 real dependencies, the rest are subs and sub-subs (after removing duplicates).

Also, some of those 39 dependencies are things I wrote (various general-purpose ORM type mappers for different styles of datastore), so I guess that number could be a bit lower.

Either way, there is a lot of verification to do here. And there's two different kinds of attacks. The dangerous attack that automated key lookups and signing can protect against would be someone publishing a malicious version n+1 of a library I wrote or rely on (either hacking the npm credentials or just buying access as in the case of the minimap / autocomplete-python debacle from last week). In that case, the key change might be noted, but then again, people lose access to keys so you'd want to have ways for package authors to revoke and reissue keys (in which case compromised or purchased credentials might not be noted).

Another type of attack is the one we're seeing here - a typo attack. Without protections of the type discussed in maybekatz's tweet (in that thread), it's pretty hard to see you're in a typo attack. The malicious publisher can still sign a malicious package, and if you accidentally install crossenv instead of cross-env, there's no protection from signing. Again, unless you are manually auditing all 500+ dependencies in your tree by figuring out who the author should be, since you're viewing the npm-reported information as potentially compromised you'll need to find other connections to that person.

At this point, you've basically recreated a web-of-trust architecture, with all the challenges that go with it. This isn't simple, I don't think isaacs and the rest of the npm crew are maliciously ignoring obvious answers. It's more likely that the actual answers are hard to find and harder to scale.

The answer ultimately is: we need to audit all the code we use, or have someone else we trust audit the code we use. And if we're not auditing it ourselves, we probably have to pay someone else to do that, and that's not cheap. Walled gardens have their benefits, but explosive growth and rapid invention / iteration / elaboration is not one of them.

2 comments

What if someone just maintained a list of "bad" npm packages, and you could run your package.json against that service to make sure you didn't accidentally install crossenv instead of cross-env?
> only tinfoil-crazies will verify that stuff

vs

> my simple webapp has 514 de-duped dependencies

We have different ideas of 'crazy'.

i've been building web-based software since 1998, when I had to manually parse http requests on stdin (and read headers from env variables) in a C application running as a cgi-bin plugin, remembering to end the stream with two \n characters. i (a) know what i am doing and (b) am super-glad i don't have to parse a lot of jank to get to the interesting parts of the code.

every approach has weaknesses. I'm pretty sure there's tradeoffs everywhere: ergonomics vs speed, security vs inclusivity, etc. I'm also pretty sure it's uncool to make implications about my mental health in public.

Like the person you are replying to, I've been developing web apps since the 1990's (1997 in my case).

I'm unconvinced that 514 is crazy.

In fact, the only unusual thing I see there is that the author knows that number.

Back in then 1990's PHP was very popular. To use it, you had to compile it yourself, which involved compiling Apache 1.3 with modules. There were also various image libraries, font libraries etc. It wouldn't surprise me at all if the dependency tree of that included hundreds of libraries.