← All fixes

Fix it

Catastrophic regex backtracking (ReDoS) — how to spot and fix it

Medium severityCWE-1333 (Inefficient Regular Expression Complexity)
We scanned nearly 2,000 AI-built apps and 1 in 8 shipped a high-severity flaw. Is this one in yours?Scan free →

Some regular expressions run in exponential time on certain inputs because the engine backtracks through an explosion of ways to match. An attacker who can send input to a vulnerable pattern can make a single short string pin a CPU core for seconds or minutes, which is a denial of service. The fix is to remove the ambiguity that causes the backtracking, usually a nested or overlapping quantifier.

Why it's a problem

On a typical event-loop server, one request stuck in a backtracking regex blocks everything else on that worker. A handful of crafted requests can take the whole service down with almost no bandwidth. Because the pattern behaves normally on ordinary input, it passes testing and only fails when someone sends the specific shape that triggers the blowup.

The pattern

// nested quantifier over an overlapping class: exponential on "aaaa...!"
const re = /^(a+)+$/;

// real-world shape: validating with (\s*\w+\s*)* style groups
const emailish = /^(\w+\s*)*@example\.com$/;

The fix

// remove the nesting; match the same language without ambiguity
const re = /^a+$/;

// anchor and avoid overlapping repeats; or validate with a parser/length cap
const emailish = /^\w+@example\.com$/;

Why AI tools write this

Assistants build regexes by composing pieces that look reasonable, and nested quantifiers like (x+)+ or (x*)* read as harmless to a model that is pattern-matching on syntax rather than reasoning about the matching engine's time complexity. The regex validates correct input in the example it was given, so nothing signals the exponential edge case.

The quick fix

  • Look for nested quantifiers such as (a+)+, (a*)*, or (a|a)* and flatten them.
  • Avoid overlapping alternations where the same character can match multiple ways.
  • Cap input length before matching, and prefer a real parser for structured formats.
  • Test suspect patterns with a long adversarial string and a timeout to confirm they stay linear.

Want to know if this pattern is already in a repo you shipped? Scan a public repo free, no account needed.

Scan a repo →

Related: Missing rate limiting

ReDoS: Catastrophic Regex Backtracking — Why It Happens and the Fix: Prbl