CVE-2024-21538 - How a ReDoS Vulnerability in cross-spawn Can Crash Your Node.js Apps
TL;DR:
If your project uses cross-spawn before version 7..5, you are vulnerable to a Regular Expression Denial of Service (ReDoS) attack. This means a bad actor can freeze or crash your app by sending a carefully crafted string. Here’s how the bug works, how to exploit it, and what to do about it.
What Is cross-spawn?
cross-spawn is a popular npm package that's used to launch new processes in Node.js, fixing some Windows issues with Node’s native child_process.spawn. With over 60 million downloads monthly, it’s a core piece for tools like webpack, Jest, and more.
What Is ReDoS?
Regular Expression Denial of Service (ReDoS) happens when poorly written regex patterns are fed complex input. This causes crazy-long backtracking, using up all CPU and making the app super slow or crash outright.
Vulnerable Code Sample
In the vulnerable versions, certain input strings to cross-spawn's command parser are not properly sanitized before passing through a regex.
A simplified version of the buggy code looks like this
// Simplified example (not actual code)
const ENV_VAR_PATTERN = /^([A-Za-z_][A-Za-z-9_]*)=(.*)$/;
function parseEnvVar(input) {
return ENV_VAR_PATTERN.exec(input);
}
The actual regex in cross-spawn is more complex, but the problem is similar: if you give it a huge and complex string, the regex can take ages to process.
Here’s a minimal proof of concept (PoC) for the vulnerable regex. You can adapt it as needed
// Proof of concept: causes extreme slowdown/crash in vulnerable versions
const crossSpawn = require('cross-spawn');
// This is a huge input that will make the regex engine go crazy
const evilInput = "A".repeat(100000) + "=value";
// The vulnerable function would process this input and hang
console.time("ReDoS");
try {
crossSpawn.parseEnvVar(evilInput); // Not a real API, but cross-spawn does this internally
} catch (err) {
console.error(err);
}
console.timeEnd("ReDoS");
When run with cross-spawn < 7..5, this script will hang or spike your CPU.
Why Does This Work?
Regex engines use "backtracking" to check all possible ways a pattern can fit your input. With bad input and a poorly optimized regex, they end up checking millions of possibilities. Your app locks up (and your server bill goes up!).
Fix: Upgrade to cross-spawn 7..5 or Above
The cross-spawn maintainers fixed the regex in this commit and released version 7..5.
To protect yourself
npm install cross-spawn@latest
# or
yarn add cross-spawn@latest
References and More Reading
- CVE-2024-21538 on GitHub Advisory Database
- Official cross-spawn changelog
- Cross-spawn GitHub repo
- OWASP: Regular Expression Denial of Service
Final Thoughts
It’s easy to overlook code dependencies, but vulnerabilities like CVE-2024-21538 are a sharp reminder:
Keep your dependencies up to date!
Regularly audit your npm packages (use npm audit if you’re not already), and don’t ignore those moderate/high alerts.
Got legacy Node apps? Double-check if they use old versions of cross-spawn. One line update can save hours of downtime.
Stay secure!
Have thoughts or questions? Drop them below.
Timeline
Published on: 11/08/2024 05:15:06 UTC
Last modified on: 11/19/2024 14:15:17 UTC