If you are running Node.js in production, it’s time to check your version numbers.
Earlier today, the Node.js team released a critical security update regarding a Denial of Service (DoS) vulnerability tied to the async_hooksmodule. If you use observability tools, tracing libraries, or AsyncLocalStorageyour application might be at risk.
In this post, we’ll break down what happened, why async_hooksis involved, and how to fix it.
What is async_hooks anyway?
Before we dive into the vulnerability, let’s recap. The async_hooks API is a powerful, low-level built-in module in Node.js that allows you to track the lifetime of asynchronous resources (like promises, timeouts, or TCP wraps).
It’s the engine behind many things we love:
- AsyncLocalStorage: Used for keeping track of request IDs across different functions.
- APM Tools: New Relic, Datadog, and OpenTelemetry use it to trace requests.
- Logging Frameworks: To inject context into your logs. Because it hooks into the very core of Node.js’s event loop, any inefficiency or bug here can have massive performance implications.
The Vulnerability: The "January 2026" DoS
The security team identified a flaw in how Node.js manages memory and resource tracking when async_hooks are enabled.
The Exploit
A malicious actor could craft specific asynchronous patterns likely involving deeply nested or recursive async calls that cause the internal resource tracking mechanism to consume an unbound amount of memory or CPU cycles.
The result? An Out-of-Memory (OOM) crash or a CPU spike that makes the server unresponsive. Because this happens at the internal level, standard application-level try-catch blocks won't save you.
Who is affected?
You are likely affected if:
- You are using an unpatched version of Node.js (v20.x, v22.x, or v24.x).
- Your application (or its dependencies) uses async_hooks or AsyncLocalStorage.
- Your server processes untrusted user input that triggers asynchronous logic.
The Fix: Update Now
The Node.js team has released patched versions for all active Long-Term Support (LTS) and Current branches.
1) Identify your version
Check your current Node.js version:
node -v
2) Update to the patched versions
Depending on your release line, you should update to at least:
- Node.js v24.x -> Update to v24.X.X (Latest)
- Node.js v22.x (LTS) -> Update to v22.X.X
- Node.js v20.x (LTS) -> Update to v20.X.X
(Note: Replace the X with the specific version numbers mentioned in the official advisory)
3) How to update
If you use nvm (Node Version Manager):
nvm install 22 --reinstall-packages-from=22
nvm use 22
If you use Docker, update your base image:
# From
FROM node:22-slim
# To the latest patch
FROM node:22.14.0-slim (or similar)
I just finished upgrading my project, to the latest LTS version. Here is the exact workflow I used to secure the environment.
If you are on Windows and using nvm-windows, follow these steps to move to the latest, most secure Long-Term Support (LTS) version.
1) Update your Node Runtime
First, we need to grab the latest LTS version (currently v24.13.0) and tell our system to use it
# Install the latest Long-Term Support version
nvm install lts
# Switch your active version to LTS
nvm use lts
Pro Tip: You can verify you are on the right version by running node -v. You should see v24.13.0.
2) Align your TypeScript Definitions
Updating Node isn't enough if you're using TypeScript. Your @types/node package needs to match your runtime so your editor knows about the latest APIs and security features.
Check your package.json. If you're on Node 24 but your types are still on ^20, you're essentially "type-blind" to the new version's features.
Run this to sync them up:
npm install --save-dev @types/node@^24
3) The Final Security Sweep
Once your environment is updated, it's time to check your actual project dependencies. Thousands of packages are updated daily to patch vulnerabilities—npm audit is your best friend here.
npm audit
If you see vulnerabilities, you can attempt an automatic fix:
npm audit fix
Temporary Mitigation (If you can't update immediately)
If for some reason you cannot update your Node.js runtime today, consider these steps:
Audit Dependencies: Check if you are using libraries like cls-hooked or older tracing agents that rely heavily on async_hooks and see if they have issued their own workarounds.
Disable Non-Essential Tracing: If you are using AsyncLocalStorage only for non-critical logging, consider disabling it temporarily in high-risk environments.
Rate Limiting: Implement aggressive rate limiting at the Reverse Proxy (Nginx/Cloudflare) level to prevent attackers from flooding your event loop with complex async requests
For more details, read the full official security blog post at nodejs.org.
Top comments (0)