Node's new vulnerability you need to know about if you're processing user data — it could crash your server
- Hex Miller-Bakewell

- Jan 22
- 2 min read
Servers running React, Next.js, or using tools like Datadog are vulnerable to a new Denial of Service attack (patched on January 13th). If you're processing user data, like we are, then your server could be at risk. Thankfully HDA isn't using server side rendering, and is not affected. Do check if you are..
What's the risk? Someone can force your server to crash by making it process malicious data.
How is it triggered? Someone sends your server a JSON object with e.g. 50k layers of nesting.
What's the cause? "Stack Exhaustion", which happens when recursive code calls itself too often and runs out of stack space. If this happens while also processing an async hook then the whole program terminates, skipping any error handling the developer has written.
How it crashes Node servers, and how they fixed it
Async hooks are triggered each time your own code does anything asynchronous (e.g. any server process). They're used in React Server Components, Next.js' request context tracking, and Application Performance Monitors like Datadog.

Combining async hooks with recursion is where we get an actual problem.
In the V8 engine any recursive code simply uses up more and more of the stack as it calls itself. When it runs out of stack space we get an error, which can then be caught and handled. Normally. Async hooks change that, because V8 wraps them in a "kFatal" context, meaning "if an error occurs while processing this async hook then just terminate, don't try to handle it."
Recursive asynchronous code makes a new Promise object with each recursive call. A new Promise means the async context has changed, which means we call all our async hooks again. Every time. If the recursion keeps going then soon the call stack is now layers of "your program code, which can handle errors fine" alternating with layers of "the async hook, which terminates your program on error". If we run out of stack space we get an error, and how the program reacts depends on which layer we're in.
The fix adds a little more nuance to the async hook's "kFatal" context, allowing Stack Overflow errors (including Stack Exhaustion) to be passed back to the error handlers without triggering termination.
Bottom line: It's not nearly as serious as December's vulnerabilities, but it can still take down your web app, so check here if your version of Node is vulnerable!



Comments