Some of the comments in this thread are wild. Huge dependency trees are bad pattern, plain and simple.
The problem isn’t only ridiculous amounts of untrusted code, but thousands of new developers of the last 10 years who think this is the way to write reliable code. Never acknowledged the risks of having everyone write your code for you, and overestimate how unique and interesting their apps are.
If you must participate in this madness, static analysis tools exist to scan your 10000 dependencies, taking security seriously is the issue.
> Huge dependency trees are bad pattern, plain and simple.
And what's the alternative? Do you write your own libraries to store and check password hashes complete with hash and salt functions? Roll your own google oauth flow? Your own user session management library?
It's madness on either side, the difference is `npm install` and pray allows you to actually get things done
A large standard library is a big part of the solution. Your project may pull in a crypto library that includes password hashing, and an oauth library, and a session management library, but all of those libraries will have few or no dependencies outside of the standard library.
Every time this discussion comes up about JavaScript ecosystem and the "problems" the solution everyone brings to the table is "Have a large standard library"
You know JavaScript doesn't have one, don't you? That is why this "issue" exists. Putting the cat back in the bag is impossible.
When vetting a dependency consider whether it depends on packages you already depend on, if new dependency tree is too large try breaking down desired functionality—multiple lower level smaller direct dependencies may have lighter overall footprint, take them and some built-ins and some of your own glue code and you get the same thing with fewer holes.
More tangentially, use persistent lockfiles and do periodic upgrades when warranted (e.g. relevant advisories are out) and check new versions getting installed.
You use a trusted standard library which has crypto functions (and lots of other helpers) and for small things you write your own.
Yes you can write your own things like session management, yes that is better than the entire web depending on a module for session management which depends on a module which depends on a module maintained by a bored teenager in Russia.
Please do check out other ecosystems, there is another way.
Using a small number of libraries, where each library provides a large amount of functionality. When I install Django, for instance, four packages are installed, and each package does a substantial amount of work. I don't have to install 1000 packages where each package is three lines of code.
When I'm writing a C program I can somehow depend on only one library for password hashing and one for oauth (maybe two if it also needs curl). In javascript land it's probably a couple dozen, probably from a couple dozen different people.
How many developers write C programs versus how many developers write JS apps?
Without accounting for that, your comparison makes no sense! Not even mentioning that you’re comparing two very different level languages. A low level language like C would never behave like a high er level language
Most of those dependencies have well defined, stable api. They use or at least try to follow semver. And you're probably only hitting about 10% of your dependencies on the critical path you're using, meaning that a lot of potentially vulnerable code is never executed.
I get the supply chain attacks. I get that you have a tree of untrusted javascript code that you're executing in your app, on install, on build and in runtime. But there's also Snyk and Dependabot which issue you alerts when your dependency tree has published CVEs.
We can talk about alert fatigue, but to be honest, I feel more secure with my node_modules folder than I do with my operating system and plethora of DLLs it loads.
I don't wanna turn this into a whataboutism argument, but at some point you gotta get to work, write some code and depend on some libraries other people have written.
> And you're probably only hitting about 10% of your dependencies on the critical path you're using, meaning that a lot of potentially vulnerable code is never executed.
If a dependency has been compromised it doesn't matter if its code is actually used, since it can include a lifecycle script that's executed at install-time, which was apparently the mechanism for the recent ua-parser-js exploit.
The problem isn’t only ridiculous amounts of untrusted code, but thousands of new developers of the last 10 years who think this is the way to write reliable code. Never acknowledged the risks of having everyone write your code for you, and overestimate how unique and interesting their apps are.
If you must participate in this madness, static analysis tools exist to scan your 10000 dependencies, taking security seriously is the issue.