Video Summary and Transcription
Introducing Node.js security overview, defining vulnerabilities, non-vulnerabilities, and preventive measures. Discussing Node.js API input validation, real vulnerabilities like HTTP server crashes, and the importance of Node.js security in widely used platforms. Discussing the importance of Node.js maintenance, the introduction of experimental permissions in Node.js 20, and the seatbelt philosophy to protect against malicious code. Discussing the importance of maintaining up-to-date Node.js versions and using tools like npx isMyNodeVulnerable for security checks. Discussing the importance of Node.js security releases, funding, and dependency vulnerability assessment for a safer Node.js environment. Using Node.js Dependency Vulnerability Assessment to evaluate and address potential vulnerabilities, ensuring automated security checks and updates for a safer Node.js environment. Automating Node.js security release process, including configuration files for dependencies, extensive testing across various environments, and creating security release issues and blog posts automatically. Support for various environments, extensive testing with over 55 suites and 5,000 unit tests, automation efforts to streamline processes, and the establishment of a maintenance threat model for enhanced security measures. For a single pull request, it takes six hours to run tests, automation efforts in progress, maintenance threat model to address security risks, permission model roadmap, ongoing discussions on security reports, and plans for the Node.js Collaborator Summit. Active community involvement in Node.js security development, four security releases from 2024 to 2026 addressing various vulnerabilities, end-of-life version strategy with Node.js 16 and 18 having high weekly downloads, and the approach to issuing CVEs for end-of-life versions. Node.js project's strategy adjustment for CVEs to include end-of-life versions, importance of Node.js threat model, trust boundaries, and developer responsibilities. Node.js protection against network data, upgrade recommendations for different Node.js versions, and upcoming changes in Node.js release schedule.
1. Analyzing Node.js Security
Introducing Node.js security overview, defining vulnerabilities, non-vulnerabilities, and preventive measures.
Hello, folks. I'm here to talk about the state of Node.js security. It's a two-year review from 2024 and 2026. We have ongoing conversations and ongoing features on Node.js, and I'm happy to share all of that with you.
So before I start, I would like to give you an overview of what exactly is a Node.js vulnerability. Not every blog qualifies as a security vulnerability. Usually, you may think that if your app crashes or if you leak memory somehow, if your HTTP server goes down due to a malicious package or something like that, you may think this is a Node.js vulnerability. But that's not true. Node.js created the Node.js security team, but we have created the Node.js threat model, which defines exactly the boundaries for security. So we clearly define what can be considered a vulnerability when you work with Node.js, what you need to prevent against, and what is Node.js' responsibility. So I'm going to share that with more details. And all the Node.js security reports go to HackerOne. So if you are fuzzing Node.js source code and you believe you found a vulnerability, feel free to send a report to us through HackerOne. I'll be reviewing all of that.
All right, so this is an example of non-vulnerability on Node.js. Imagine you install a package, and this package changes the prototype of array push. So whenever you call array, any array, .push, it will display intercepted and the array won't include a new item. So you may think, OK, my code is now vulnerable. In fact, you are vulnerable, but that's not a Node.js vulnerability. It's something that you should create measures against that, which is to make sure to install the right packages. Always take a look at the packages you install when running Node.js. So for this specific situation, we have a flag called --"FrozenIntrinsics." So whenever you run your app with that, people or any user shouldn't be able to modify prototypes of native or primitive data of Node.js. Try to use that, but that's not a security measure. It's just a seatbelt, and we are going to talk about that later. We have a lot more examples of non-vulnerabilities. It's all described in the Node.js threat model. For instance, prototype pollution, this is not a Node.js vulnerability. When you install a malicious third-party module, this is not a Node.js vulnerability. All of that is something that you should create measures against that in your production app. So for instance, imagine you have an HTTP server that receives an input from untrusted input.
2. Node.js Security Best Practices
Discussing Node.js API input validation, real vulnerabilities like HTTP server crashes, and the importance of Node.js security in widely used platforms.
So what happens is that you don't validate that input, and you pass that to a Node.js API. For instance, path.join, and then you serve that file. If the remote input sends a path traversal, it could access different files of your file system. This is not a Node.js vulnerability. You need to change the input and sanitize that before passing to Node.js APIs. So we have plenty of other examples in your documentation. We have the Node.js best practice security. It's a document we wrote. It's available on the Node.js.org website, and you can check that easily.
And we have some examples of real vulnerabilities, which is the CVEs we normally issue against. So, for instance, if you have an HTTP server, and based on the request from anyone, it could close or crash your HTTP server. This is a vulnerability. This is something that Node.js should protect against. So if you experience that somehow, you need to report that to Node.js, and we will be fixing that as soon as possible. The same happens for HTTP request smuggling, timing attacks, memory access violations, or any kind of information exposures. We had one report not so long ago about DNS rebinding, where whenever you run Node.js with Inspector protocol, that could leak the Inspector through the internet to the network, and that was fixed already. So make sure to upgrade your Node.js version.
We are talking about Node.js. Node.js is widely used. If you use Discord, you use Node.js. If you use Slack, you use Node.js. Everybody, basically, is using Node.js at some point, either in their production apps or using that in other providers like Discord, Slack, other platforms. Security is a must. We have billions of annual downloads. We have millions of production deployments, and a single vulnerability in Node.js Core can cascade to millions of production deployments in a few hours. That's why all work in Node.js security is essential. That's why, also, I highly suggest you, if you can, help us maintaining Node.js.
3. Node.js Permission Model and Security Measures
Discussing the importance of Node.js maintenance, the introduction of experimental permissions in Node.js 20, and the seatbelt philosophy to protect against malicious code.
That's why, also, I highly suggest you, if you can, help us maintaining Node.js. One feature that we created since Node.js 20, so if you use Node.js 20 or more, and you should be using that because Node.js 18 is end of life at the moment I'm recording this presentation. Since Node.js 20, we have introduced the dash dash experimental permission, and we have stabilized that in the Node.js 23, so you can use only the dash dash permission flag. And the permission model is basically restrict access to your app, to file system, to child process, to worker threads, native add-ons, web, Wazzy, network. This is experimental at the moment. And imagine that you are trying to solve a problem. Usually, you go to your LLM2, and it suggests you to install a package. And this package might have been hijacked somehow, and you install that package. And although the package does solve the problem, it does things behind the scenes that you are not aware of, like reading some sensitive files, or reading those files and sending to the Internet, which is something that you don't want. And this permission model feature is a seatbelt that will help you against that.
So whenever you run Node.js with permission flag, you must provide the folders or the files you allow read access or write access, or the same applies to network. If you don't provide that, Node.js will block. And this is a seatbelt that I highly suggest you to use that. And I'm talking about seatbelt philosophy a lot, but I'm going to explain why, even with those security measures, you should not run malicious code in Node.js. The thread model defines that with trust in the code run. So if you get the code from the Internet, if you receive a code from input and you run that, if you evaluate that, this is against Node.js thread model. Even with the permission model philosophy, there are ways to bypass that using sim links with race conditions, and no single feature of Node.js will let you run untrusted code safely. This is by JavaScript designer, I would say. But this is a seatbelt.
4. Node.js Security Maintenance and Version Check
Discussing the importance of maintaining up-to-date Node.js versions and using tools like npx isMyNodeVulnerable for security checks.
As many layers, as security layers, you could add it to your project, the barrel, right? So that's the idea of the permission model. I highly suggest you to check it, and we have other measures that I'm going to talk about through this call, okay?
The next one is npx isMyNodeGenerable. I have shared that many times. This is a QR code to the repository. And basically, we have data that tells us that a lot of users are using end-of-life versions of Node.js. So, for instance, whenever we release a new version, I'm also a Node.js releaser, and we usually release several measures of Node.js twice per year. And every time I release that, we go to the X LinkedIn, and we saw the comments. People say, oh my God, you are a Node.js 25. I'm still Node.js 12 or Node.js 16.
All those versions are end-of-life, and this is very problematic, because any security patch we issue, we fix, doesn't go to those lines, which means that you are insecure. If we release a security patch that is a zero-day vulnerability, you will be affected because we won't patch that version. You must upgrade, especially if you are using production servers. And if you don't know exactly if you are using the correct version of Node.js, make sure to run npx isMyNodeVulnerable in a terminal. This should display a danger if you are insecure, or a good message if you are using a secure version of Node.js, okay?
5. Node.js Security Funding and Dependency Assessment
Discussing the importance of Node.js security releases, funding, and dependency vulnerability assessment for a safer Node.js environment.
This is behind the Node.js organization. We have also designed that for CI pipelines, developer workstations, and you can use that for different audits. For instance, before sending your code to production, you can run that, and if that displays an error message, you prevent that deploy. So this is very important to get notified about Node.js security releases, okay? So as I said, this tool is especially critical for more than 120 million downloads Node.js has for end-of-life versions, Node.js 18 and below. That's it, okay?
Moving on. We are going to talk about the Alpha Omega Initiative. I've been sponsored by the OpenSSF Alpha Omega Initiative for the last four years. This funding enabled me to work full-time in Node.js security. I've been working and handling Node.js security for the last four to five years, and we have done different measures that help Node.js developers to have a more safe environment. One thing very important to mention here is that while reviewing HackerOne reports, we have discovered that most of the vulnerabilities do not affect production servers. They affect developers. So if you are trying to solve a problem by installing a package running on very weird code in your developer machine, you are insecure, okay?
I have a talk called 5 Ways You Could Have Hacked Node.js. I have presented that three years ago, and that still applies to Node.js 2026. I highly suggest you to take a look at that. I exposed 5 vulnerabilities that Node.js fixed that could affect people using end-of-life versions of Node.js. Through this sponsorship, I could work on Node.js security, fix those patches, improve Node.js security processes, and include some features in the security. One of the assessments or initiatives we had on Node.js security workgroup is the dependency vulnerability assessment. Node.js, at the moment I'm recording this presentation, we have 26 native dependencies. OpenSSL, energy, HTTP2, LL, HTTP, Libby v8, we have any crypto, we have way more, and all those are bundled inside Node.js binary, which means that if any of those dependencies contain a vulnerability in one of the APIs Node.js use, for instance, OpenSSL, Node.js will be affected by that, might be affected by that.
6. Node.js Dependency Vulnerability Assessment
Using Node.js Dependency Vulnerability Assessment to evaluate and address potential vulnerabilities, ensuring automated security checks and updates for a safer Node.js environment.
We use several OpenSSL APIs, and we expose that to users. If any of those versions, any of those APIs contains a vulnerability, Node.js will be affected by that, might be affected by that, and for that reason, we have an automation. We have a repository called the Node.js Dependency Vulnerability Assessment. I know that is the long name, but it is what it is. You can go to that repository, you see the issues, and whenever a public CV is found to any of four dependencies, for instance, OpenSSL, it creates an issue.
The Node.js security team will evaluate if that affects Node.js or not. If that affects, we either fix that in a security release, or we define, okay, this is a low severity, it's unlikely to affect our users, and we are going to fix that anyway, but following the regular release process. So imagine that you use a security scanner. A lot of people does that in production. The security scanner points that Node.js 24.8.0 is vulnerable to, because it contains a min match dependency, and you don't know exactly what to do because Node.js didn't patch that.
Then you can go to that repository, possibly there will be an issue about that, and we will say, okay, this is pointing to in your security scanner, but this does not affect you. It's just a false positive, and we are going to fix that following the regular release schedule, but this won't affect you. You don't need to worry about that, okay? And any question can be asked there as well. And it's also important to mention that most, if not all, of those dependencies, we have automatic updates.
7. Automating Node.js Security Release Process
Automating Node.js security release process, including configuration files for dependencies, extensive testing across various environments, and creating security release issues and blog posts automatically.
So whenever there's a new version of OpenSSL, we have a bot that will open up a request. It's kind of dependable, but we have more specific configuration files for each dependency that needs to create or is dependable for those versions. It's also very interesting. If you want to learn more about that, feel free to ping me, okay?
So moving on, we have some ongoing security working group discussions. We are automating the security release process. Node.js contains a very long security release schedule, and we are going to talk more about that. Usually, it takes at least two weeks of work to issue a Node.js security release, which is very tough, to be honest.
Now we have a CLI that creates the security release issue. It fetches all the reports. We have a request ready from HackerOne. We have an automation that creates the blog post for the security release to send a message because Node.js is not simple. Node.js supports different environments like Windows, Windows 64-bits, Windows Server, MacOS, Ubuntu, ARM64, and different architectures. We need to have binaries for all those environments and test the Node.js binary against all those environments. Currently, we have more than 55 suites of tests, which means almost 5,000 unit tests, and we run each batch of tests in each one of the environments. It's quite an extensive process.
8. Enhancing Node.js Security Measures
Support for various environments, extensive testing with over 55 suites and 5,000 unit tests, automation efforts to streamline processes, and the establishment of a maintenance threat model for enhanced security measures.
We have support to Windows, Windows 64-bits, Windows Server, MacOS, Ubuntu, ARM64, and different architectures. It's essential to have binaries for all these environments and test the Node.js binary across them. Currently, there are over 55 test suites, totaling almost 5,000 unit tests, run in each environment batch, making the process quite extensive. For a single pull request, running tests alone can take about six hours, ensuring compatibility with popular packages like Express among others.
Automation plays a crucial role in streamlining this time-consuming process, although it doesn't directly speed it up; it significantly reduces maintenance needs. The team has been working on automating tasks for over a year, making good progress, but there is still much to accomplish. Collaboration is encouraged to aid in this ongoing effort. Additionally, a maintenance threat model has been established to address potential security risks within the Node.js organization, outlining roles, access restrictions, and specific scopes for different teams to enhance security.
The threat model specifically focuses on mitigating risks from various collaborators, including the website team, by defining and restricting access to critical resources like the Node.js.org repository while preventing access to sensitive areas like build machines. This structured approach enhances security measures within the organization, providing clarity on roles and access levels. The detailed roles and access control strategy offer a comprehensive framework to safeguard the integrity of the Node.js binary and related operations, ensuring a robust security posture.
9. Node.js Security Automation and Collaboration
For a single pull request, it takes six hours to run tests, automation efforts in progress, maintenance threat model to address security risks, permission model roadmap, ongoing discussions on security reports, and plans for the Node.js Collaborator Summit.
It's a lot. And for a single pull request, it usually takes, I don't know, six hours to run just the tests. And then we check if our binary is ready to go because we check, okay, will this break a popular package like Express? We test the new binary, we run the Express test with the new binary and check if that breaks. And we do that for more than 100 packages. So it's a lot. It takes a lot of time. And we are trying to automate most of the process. And although it won't make the process faster, it will reduce the maintenance because usually we need at least five people to create a secret release of Node.js.
Okay, we are in progress. We have been doing that for more than a year. We have a good progress, but there is still a lot of things to do. And we invite you to help us on that front. We have also the maintenance threat model, which is, we have defined the Node.js threat model, but Node.js is a big organization. We have more than 100 collaborators. And what about the folks from the website team, get rejected? What are they can do? What are one person, a malicious person, that have access to the website could do to the Node.js binary? We have created a long list of the roles and the access they have. And then we have restricted the scopes to a specific situation. So the website team has only access to the Node.js.org repository, but they can't access the build machines, for instance. And then we have created that, and this is very helpful.
It's concluded, you can check the list and the table as well. We have also, as I mentioned before, the permission model roadmap, we have created that. And this was a pull request that took eight months to land. And we had more than 500 discussions in that request. It's a long list, but we finally have that landed in this table. You can use that. There is two ongoing discussions, that at the time of recording that, we are actively discussing, which is moving security reports to public workflow. Node.js will have the Node.js Collaborator Summit in April 14th to April 15th in London. I will be there, and I'm going to discuss these two issues. The first one is, what about handling security reports in public? This is quite controversial, and I'm not sure the details about that in this call, because in the time you'll be watching this, a lot might have changed. So I highly suggest you to take a look on this issue on the Node.js TSC channel. And the second one is creating a model, LLM model to help us triage HackerOne reports.
10. Node.js Security Releases and End-of-Life Strategy
Active community involvement in Node.js security development, four security releases from 2024 to 2026 addressing various vulnerabilities, end-of-life version strategy with Node.js 16 and 18 having high weekly downloads, and the approach to issuing CVEs for end-of-life versions.
All of that is active development, and we expect some involvement from the community. So if you want to help, this would be a very good way to help. Next one is security releases. Node.js, if I'm not wrong, from 2024 to 2026, we have issued four security releases. February 14th, we have fixed Morphine attack, multiple permission model bypasses, because in 2024, the permission model was still experimental. So it means any bug in that feature experimental is still a security vulnerability, because it's a seatbelt, right? And then we have the April 3rd, we have HTTP2 DOS, NGTPP2 race condition. A lot of HTTP requests is smuggling. It was another security release. Then we had another one in April.
The next one was in July, January 21. The last one was January 13, which we fixed in eight vulnerabilities, also in HTTP2. Async hooks, DOS, for this one specifically, I'm pretty sure you know about that because this affected Next applications by DOS. Next and also any APM like Datadog, New Relic. So all those security releases, we have a kind of post-mortem blog post, which explains the vulnerability and how we fixed that. So if you want to learn more about Node.js, feel free to take a look at those blog posts. It's all available on nodejs.org, okay?
And then one thing, very important, the end-of-life version strategy. I have mentioned here that despite being end-of-life, Node.js 16 and 18 had over 120 million downloads weekly, okay? And in 2025, this represents almost 30% of the Node.js ecosystem, okay? The solution, we have tried many ways to solve that. And one of that was, what about issuing a CVE to all those end-of-life versions? This is totally against the usual strategy of issuing CVEs. One CVE should have one vulnerability per definition, but we tried, okay, if folks are using security scanners a lot and they are using end-of-life versions, if we issue a CVE to those versions without a patch, they will feel the danger and they will need to upgrade that. We tried, we received good community feedback from Node.js users, but we also received a bad feedback from Mitre and the security researchers because this is against the CVE definition.
11. Node.js Threat Model and Trust Boundaries
Node.js project's strategy adjustment for CVEs to include end-of-life versions, importance of Node.js threat model, trust boundaries, and developer responsibilities.
Our second solution was, the Node.js project cannot retroactively evaluate more than 20 end-of-life versions. It's a lot. It's out of Node.js maintenance proposal, okay? And we pivoted our strategy to all new CVEs now explicitly include end-of-life release lines. So from now on, any CVE that we issue, we also include the Node.js 4, Node.js 5, 6, 7, 8, 10 to the range of affected CVE list, okay? So if we are going to release on CVE for HTTP2, we are going to also include Node.js 18, Node.js 16 to the list of affected versions. This might help.
And I mentioned before, Node.js threat model is very important. You can check it on the Node.js security policy. And what exactly is a threat model? So it basically defines what is the boundaries of security in Node.js? What can be considered a vulnerability and what cannot? What Node.js protect against natively and what we don't. So for the situations we don't protect you against, you need to sanitize the input, for instance, HTTP remote input. You should not evaluate that. Node.js does not create measures against that. We will never sanitize the remote input because that's against ARFC rules, HTTP specification. It's your obligation as a developer to do that, to validate input and validate output as well.
And what Node.js does trust? We trust, the things we trust is basically, when we say we trust, it means we don't create measures against that. So if you are running Node.js in an insecure environment, like an old Ubuntu version or a file system shared with different malicious users, we just trust in the file system. If we are using that in an unsafe environment, it's your choice and you might be vulnerable to that. And this is not Node.js responsibility. Operating system, all the code it runs, so you can't copy a code from internet and run that and expect that Node.js will protect you against that. This is wrong. For instance, you get a remote input from your HTTP server and you do a JSON dot parse. If the malicious user passed a really long JSON, you can go out of memory and your process can crash because of Out-of-memory killer. So this is your responsibility.
12. Node.js Security Evolution and Release Changes
Node.js protection against network data, upgrade recommendations for different Node.js versions, and upcoming changes in Node.js release schedule.
And what Node.js protects you against? Inbound and outbound network data. If someone sends you a request and before processing that, your server crashes, this is Node.js fault and this possibly is a Node.js vulnerability. If you are consuming a file and your process crash, this is Node.js fault. So we have a long list of examples in your threat model and I have a suggestion to check it out.
Just to finalize here, if you are Node.js 18 or below, please upgrade. If you are Node.js 20, at the time I'm talking about that, it's still active but will be end of life in the end of April, 2026. And if you are Node.js 22, you are safe but consider upgrading to Node.js 24 and you should have a plan of migration to Node.js 26. That should go out on April, 2026. We are going to change the Node.js release schedule. It's another discussion but take a look on the announcements we are going to do.
Just as a spoiler, the new release strategy will start with Node.js 27 and we will have just one release line per year. Node.js 27 will be on Node.js 2027. Node.js 28 will be on 2028 and we will have just one per year and all those versions will be LTS. So for those that don't rely on all the versions, you can do that now. It's starting with Node.js 27. It's another talk. If you want to learn more about that, feel free to ping me on GitHub, Slack, X, doesn't matter. And that's it, that's it. One last comment is security is a journey, it's not a destination. We will never end with security. It will never be concluded and thankfully to NodeSource, to Alpha Omega OpenJS Foundation, they sponsored me to work on that and help Node.js developers to make a more secure environment. Thank you to all the volunteers to keep Node.js secure and to the working groups I participate in. Thank you, folks. This is how you can get involved. Bye-bye.
Comments