Regex Denial of Service (ReDoS) Prevention0%

Regex Denial of Service (ReDoS) Prevention

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Regex Denial of Service (ReDoS) Prevention in Modern JavaScript

A critical security vulnerability affecting Node.js microservices and web applications is Regular Expression Denial of Service (ReDoS). An inefficient regex containing nested quantifiers can trigger Catastrophic Backtracking when fed crafted user input—locking up the single-threaded Event Loop and consuming 100% CPU indefinitely.


1. What is Catastrophic Backtracking?

Regular expression engines use backtracking to try alternative match paths when evaluation fails. If a regex contains ambiguous, overlapping nested quantifiers, the number of potential matching paths grows exponentially ($O(2^n)$):

JavaScript
// THE VULNERABLE REGEX:
const evilRegex = /(a+)+$/;
Output
Input: "aaaaaaaaaaaaaaaaaaaaaaaaaaaa!" (28 'a's followed by exclamation)
• Path 1: (a)(a)(a)... fails at '!'
• Path 2: (aa)(a)... fails at '!'
• Path 3: (a)(aa)... fails at '!'
... The engine evaluates 2^28 (268,435,456) permutations before failing!
Result: Node.js main thread freezes for over 4 minutes!

2. Common Vulnerable Patterns (Evil Regexes)

  1. 1
    Nested Quantifiers: (x+)+, (a*)*, ([a-zA-Z]+)*
  2. 2
    Overlapping Alternation inside Quantifiers: (a|a)+$, (a|ab)+$
  3. 3
    Repeated Wildcard Captures: .*.*=
JavaScript
// DANGEROUS: Email regex frequently found in older tutorials:
const badEmail = /^([a-zA-Z0-9_\.-]+)+@([\da-zA-Z\.-]+)\.([a-zA-Z\.]{2,6})$/;
// Input: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!" locks the server completely!

3. Strategies to Prevent ReDoS

1. Eliminate Nested Quantifiers

Flatten nested quantifiers into simple, mutually exclusive character classes:

JavaScript
// SAFE: Linear O(N) evaluation
const safePattern = /^[a-zA-Z0-9_\.-]+@[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,6}$/;

2. Restrict Input Length

Never run complex regular expressions against arbitrarily long strings:

JavaScript
function validateInput(str) {
// Guard clause: limit string length to prevent polynomial exhaustion
if (typeof str !== 'string' || str.length > 256) {
return false;
}
return myRegex.test(str);
}

3. Offload Regex to Web Workers (Browser) or Worker Threads (Node.js)

If evaluating user-supplied regular expressions, isolate them in a worker thread with an execution timeout to prevent freezing the main thread:

JavaScript
// In Node.js: Worker Thread with 500ms timeout
const worker = new Worker('./regexWorker.js', { workerData: { regex, input } });
 
const timeout = setTimeout(() => {
worker.terminate(); // Kill thread if catastrophic backtracking occurs!
console.error('ReDoS Attack detected and mitigated!');
}, 500);

Interactive Quiz

Practice Quiz

Question 1
What causes a Regular Expression Denial of Service (ReDoS) attack?
Question 2
Which of the following regular expressions represents an "Evil Regex" vulnerable to ReDoS?
Question 3
Why is ReDoS particularly devastating in Node.js backend applications?
Question 4
What simple defensive check should always precede regex evaluation on user inputs?
Question 5
How can a platform safely evaluate untrusted, user-defined regular expressions?
Next Lesson

Advanced Pattern Matching & Replacement

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext