26 Nov 2018 - by 'Maurits van der Schee'

Last week, it seemed like somebody tried to steal from Bitcoin wallets using a rogue release of event-stream a JavaScript dependency (that is used a lot). You can read about it on the "I dont know what to say" issue on it's GitHub issue tracker. I'll discuss the background of this event in this post.

TLDR;

JavaScript projects use lots of (often transitive) dependencies, because JavaScript has no good standard library. If one of these dependencies falls into the hands of a malicious actor, then many websites may be vulnerable (event-stream) or broken (leftpad). These problems have nothing to do with JavaScript or Node, but with the hidden costs of dependencies.

Reactions

People are angry at the author of the dependency:

You put at risk millions of people, and making something for free, but public, means you are responsible for the package. There is a huge difference between not maintaining a repo/package, vs giving it away to a hacker (which actually takes more effort than doing nothing)

And full of good advice for the readers of the issue:

maintainers should start using static dependencies and update dependencies only after code reviews. If you want security maybe move away from node.

But they seem not to address the real issue: the hidden costs of dependencies.

The 3 hidden costs of dependencies

The developer community seems to agree that it is bad to "reinvent the wheel" and that suffering from "not-invented-here" syndrome is bad. Unfortunately they forgot to warn us for the "hidden costs of dependencies".

Availability risk: will your dependency be maintained?

Security risk: can your dependency be trusted?

Compatibility risk: will your dependency be compatible?

I'll give some examples of these below.

Hidden cost #1: Availability risk

Dependencies may have bugs that are not fixed in a timely manner. They could also be pulled offline for legal reasons. Sometimes we see forks appear to guarantee availability, but these new dependencies have an even bigger concern for security and compatibility.

Hidden cost #2: Security risk

Who wrote the code? Does the author publish a real name and contact details? I think successful (well-known) developers (especially at larger corporations) are less likely to sell out as they have a reputation to protect and most likely no need for making a quick buck.

Hidden cost #3: Compatibility risk

Will the API use semantic versioning and stay stable? Will the dependency not drop support for certain browsers or operating systems? How about the licenses of the chosen (transitive) dependencies, will these be compatible with yours, now and in the future?

Final words

This is a difficult problem that is not specific to JavaScript or Node. Any programming language that requires lots of small (transitive) dependencies will suffer from this. This is also where the solution lies. Choose a programming language with a strong standard library and use only a handful of large, popular and well maintained dependencies. And for other (small) parts, just write some well-tested function libraries that help you to solve the problems in your domain (it may even be fun to get your hands dirty).

Happy coding!

PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.