Web App Security - The state of dependencies and vulnerabilities on the node ecosystem

Guilherme Rossato, Jul. 2023 - Dec. 2023
Modern web apps are built with large frameworks like React, Nestjs, Gatsby, and therefore depend on countless smaller libraries and packages developed by people with varying levels of concerns for security. Often vulnerabilities slip through on these packages which increases the attack surface for hackers to use on our apps.
(Reportedvulnerabilities on the NPM ecosystem I extracted fromGithub)

When a vulnerability is found on a dependency they are published to a security advisory database so that other developers can be made aware of the affected packages and the risk associated with it. Today there are approximately 222,538 reported vulnerabilities onGithub's advisory databaseacross all ecosystems and this number continues to grow.

This type of tech debt often not prioritized even though everyone describes the security of their apps as extremely important. CI/CD pipelines will happily deploy a project even when multiple known vulnerabilies of the highest level of severity are present on their project, straight to production with all their users data.
npm audit --audit-level=critical

This command fails in the presence of maximum severity vulnerabilities.

Developers have to periodically dedicate some time to address these known vulnerabilities, especially if a critical severity vulnerability is present on one of the dependencies of a project.
The Node Package Manager (NPM) also informs the vulnerabilities found when you install the dependencies of a project with npm install. Here's the output on a new Gatsby project (created with the official tool) as of late 2023:
NPM install on a new Gatsby
In this case a Gatsby project is vulnerable to arbitrary code execution on compile time because of a plugin of the bundler, not exactly life treatening because it is hard for a hacker to add files to your project before the build phase takes place, but the information of vulnerability reports are public, so is the source code of the solutions, and they can be used to target vulnerable projects:
For example, there's a SQL injection report on a popular web-based project called FUXA that is used primarily by university students and professors to create visualizations of processes of machines. The report suggests (correctly) that running the project on versions below v1.1.15 fully exposes the SQL database it is connected to because of unsanitized user input on an api endpoint:

What to do about it?

The best bet is to regularly dedicate some developer time to focus on the audits, something between one and two days every month should suffice but that is just my suggestion as someone who looked and researched the problem.
Unless critical vulnerabilities occur: then have to deal with them by either updating the packages or by introducing changes to prevent the vulnerability from being taken advantage of.
Also, CI/CD pipelines should be configured to reject pull requests, pause deployment, or at the very least communicate when a sufficiently important vulnerability is detected.

My Personal Research

I wanted to know the extent of these problems and how they grow over time, so I set out to bootstrap the most commonly used web frameworks and document the evolution of their vulnerabilities by running npm audit periodically.
I started this research on mid 2023 on Node v18.7.0 (LTS) and the last update was on late 2023 on Node v20.9.0 (LTS). Here is a list of the frameworks I am testing:
Package version
v13.4.5
v1.17.0
v5.11.0
v16.1.0
v2.15.8
v3.5.2
v3.54.0
v5.9.0
v18.1.0
Creation command
npx create-next-app [name]
npx create-remix [name]
npx create-gatsby
ng new [name]
npm init nuxt-app [name]
npx nuxi@latest init [name]
npm create svelte@latest [name]
npm init adonis-ts-app@latest [name]
npx create-react-app [name]
Vulnerabilities on install
Yes, shown
No
Yes, hidden
No
Yes, hidden
No
No
Yes, hidden
Yes, shown
And here is a graph with the test results so far:

Evolution of the number of vulnerabilities of popular web frameworks

Severity:
Adonis
TotalCritical
Under development
Angular
TotalCritical
Under development
Nextjs
TotalCritical
Under development
Nuxt-2
TotalCritical
Under development
Nuxt-3
TotalCritical
Under development
Remix
TotalCritical
Under development
Svelte
TotalCritical
Under development
As time goes on I'll update this post with the results and some analysis about them. I don't know how long it takes for most of these to show up with vulnerabilities but I reckon it's in a few months.

Observations and Conclusions

I will be adding my observations and notes that come up as the search goes on and more data is available.

Most common vulnerability

Regular Expression Denial of Service (ReDoS) is the most common type of vulnerability that shows up: almost all projects has had one of those. I wouldn't classify that as moderate severity though.
The weakness that this causes is categorized as Uncontrolled Resource Consumption. The idea is that if an attacker knows of a input that goes through one of these vulnerable expressions he can craft a string that takes an enourmous time to process. When writing regex expressions it is easy to scale their duration exponentially, and since the code for the dependencies is freely available it is easy to experiment and generate abusive scripts to burn through cpu time on a server hosting one of these vulnerable apps and causing extra charges from Cloud Providers.

Adonis with breaking changes

In just two weeks after I started this research we already have the need of "breaking changes": which is when a major version has to be changed to fix a vulnerability, examples include @adonisjs/assembler@1.1.1

Nuxt interactive install

After installing and updating the nuxt 3 app a few times, they added an interactive postinstall script to ask to collect usage data which I found to be rather annoying as it broke my testing setup.

Ongoing research

This post was last updated in 2023-12-06, my research on these vulnerabilities has not been finished yet, and I wil lbe updating this post every few months to add more data or observations.