HACKER Q&A
📣 noduerme

Why is Node.js more susceptible to supply chain attacks than e.g. PHP?


I guess npm package naming anarchy and dependency rot come to mind, and security weaknesses inherent in distributed FOSS development. But inherently there's nothing a bad js script can do to your server that a malicious php script couldn't have done twenty years ago if you used the wrong package. Why has supply poisoning become such a problem with the Nodejs ecosystem in particular?


  👤 krapp Accepted Answer ✓
Because Node packages are too fine-grained meaning the dependency trees and attack surface are greater - what in PHP would be a single library from a single vendor could be a thousand packages in Node.

Because PHP packages are vendored by default, so there's an implicit stopgap on the propagation of issues from upstream.

Because PHP isn't dependent on a single vendor with a single global namespace, which avoids several of the issues you mentioned.

You can basically repeat that for other languages whose ecosystems benefit from the wisdom of years accumulated around package management and library design that Node seems to ignore.

edit: and the more I think about it, I suspect a lot of the bad practices in the modern JS ecosystem are due to the paradigm of having the same language running in the browser and on the server. This creates conflicting incentives in the way things are designed and deployed and one necessarily undermines the other.


👤 _wldu
I'm not sure it is. Software development has become more decentralized and more complex than it was 20 years ago. It's also much more accessible to more people who may be great programmers but not really aware of code/repository security.

Most software developers do not sign their git commits. And if they do, they probably aren't doing it properly (store keys on a YubiKey or only use QubesOS with an isolated dev qube and split GPG).

If you do any sort of dev work, you really need to isolate that activity from the other things you do online and generate a signing only GPG subkey and handle it properly and sign all of your git commits. I think this is vital to ensuring code integrity as if you do not do this, you probably won't even realize when someone has tampered with your code.

Hope this helps.


👤 melony
Most replies here are missing the forest for the trees. The oft not acknowledged reason is that the JS ecosystem has a developer experience that scales a lot better than other languages. Your Java/Python/Dart/Ruby (or C++ if you include tooling like dpkg and brew) dependency managers suffer from what's commonly referred to as "dependency hell", or what in certain specific cases is called the diamond dependencies problem. They fundamentally don't scale and you get package conflicts easily. The npm approach (which was later adopted by Rust and Go) allows for installation of dependencies with arbitrarily large dependency trees without having to worry about hacks like Java's dependency shading or namespace conflicts (most of the time at least). People may complain about JS dependency managers' upstream security problems, but from a classic CS point of view, it is inherently superior as it reduces the amortized complexity of a SAT solver to a much simpler backtracking resolver.

See feross's reply for a better explanation: https://news.ycombinator.com/item?id=30964442

Things like vendoring, upstream version metadata to reduce redundant network requests, SHA verification, are all easy to add after the fact. Support for arbitrary dependencies on the other hand often require a certain amount of support on the compiler level (to detect conflicting exported data structures) which is why many languages cannot easily switch to newer package management architectures.


👤 tored
Beside the technical aspects that others already mentioned, I think there is also a social aspect. PHP vs Node is like the old Apple ads "I'm a Mac vs I'm a PC" where Node is Mac, it is modern and the future, the person is dressed as slacker and taking it cool. PHP is PC, old school with a blazer and pens in his shirt pocket, your class mate who came to school with an attaché case. It is in-group vs out-group.

If you are going to target something, you pick what you think is going to get the most effect, thus you pick the in-group, not the out-group.

PHP is in-group in one area and that is Wordpress, and of course it also constantly targeted.


👤 tintedfireglass
Node js has ridiculously large dependancy trees. There is is this joke that a hello world program in NodeJS is only complete when it has 200 dependancies. If one of those many npm modules has a backdoor/vulnerability then you are screwed which is not the case for other languages.

👤 anecd0te
There's more stuff worth breaking today in JS than there was twenty years ago in PHP, and more people that know how to do it.