Every now and then, we come across vulnerabilities that, at first glance, seem too simple to wreak havoc. CVE-2022-25918—a Regular Expression Denial of Service (ReDoS) flaw in the shescape npm package—is one of those sneaky bugs hiding in plain sight. In this exclusive guide, we’ll break down what happened, walk through the buggy code, and even show you how to exploit it, all in plain English. If you use child processes or shell commands in Node.js, you’ll want to read this.
What is shescape?
shescape is a widely-used Node.js library designed to safely escape shell arguments—so you don’t inject something dangerous unintentionally. Developers trust it to keep their scripts and commands secure.
Summary
The problem was in the function escapeArgBash, inside index.js. This function used a regular expression that, for certain crafted input, could take a *huge* amount of CPU time—potentially freezing your app (Denial of Service). This is known as a ReDoS attack.
Looking Closer: The Vulnerable Code
Here’s a simplified version of the vulnerable function from GitHub source:
function escapeArgBash(arg) {
if (/^[a-zA-Z-9_\/\-\.]+$/.test(arg)) {
return arg;
}
// Problematic regex below!
return "'" + arg.replace(/'/g, '\'"\'"\'') + "'";
}
The real problem comes when user input is not sanitized and hits this regex. In some earlier shescape releases, the regex processing in escape and escapeArgBash functions allowed malicious attackers to pass in a string that would eat up CPU cycles for *seconds or minutes* at a time.
Demonstrating the Attack: Exploit Example
Let’s say you have a Node.js app using shescape v1.5.10 to escape shell arguments from users. Here’s how an attacker can freeze your server:
POC Code Snippet
const shescape = require('shescape');
// This triggers the problematic regex
let evilInput = "a'_".repeat(100000); // Large, crafted input
// This line will hang/freeze your CPU!
const result = shescape.escape(evilInput);
console.log('Escaped:', result);
How Could this Happen?
Let’s say you accept search parameters or filenames or run shell commands based on any external input. If you pass that string to shescape.escape or shescape.escapeArg, a malicious user could easily freeze your API for seconds (or worse).
How Was It Fixed?
The maintainer patched it in v1.6.1 by re-writing the regular expression and ensuring it’s not susceptible to catastrophic backtracking.
Step 1: Upgrade Now
If you use shescape below v1.6.1:
npm install shescape@latest
Step 2: Audit All Shell-escaping Code
Wherever you escape shell arguments, make sure your methods are safe from ReDoS attacks.
Step 3: Restrict User Input When Possible
Sanitize input, validate types, and, if possible, avoid passing user data directly into shell commands.
References
- Original CVE-2022-25918 Advisory
- GitHub Security Advisory on shescape
- Relevant Source Patch
Final Word
Even “helper” libraries like shescape can hide dangerous bugs. If you handle user input and use community packages, stay in the habit of running npm audit frequently and updating your dependencies. Don’t let a tiny regex take your app down!
Questions? Want to see more exploit demos or safe escaping patterns for Node.js? Let me know in the comments!
Timeline
Published on: 10/27/2022 10:15:00 UTC
Last modified on: 10/28/2022 19:41:00 UTC