FlawOpen

flawopen.com/ReDoS/JavaScript RegExp

Is JavaScript's RegExp vulnerable to ReDoS?

CWE-1333: Inefficient Regular Expression ComplexityReference page
Short answer

Think of a clerk trying every possible way to split a stack of forms whenever a required final mark is missing: an ambiguous pattern can force the regex engine to revisit many of the same characters. V8’s usual RegExp path can backtrack this way; a bounded input and a pattern with predictable work limit the cost. Node’s synchronous match runs on the event-loop thread, so a long match delays other callbacks in that process. V8 documents an experimental non-backtracking engine behind flags with pattern limitations; do not assume production Node enables it.

VULNERABLE
// Ambiguous nested repetition on request data
const re = /^(\w+\s?)*$/;

app.post('/search', (req, res) => {
  const q = req.body.q;
  if (!re.test(q)) return res.sendStatus(400);
  res.sendStatus(200);
});
FIXED
// Bound input and accept only the field grammar
app.post('/search', (req, res) => {
  const q = req.body.q;
  if (typeof q !== 'string' || q.length > 128)
    return res.sendStatus(400);

  // Example grammar: ASCII word chars and spaces only
  if (!/^[\w ]{1,128}$/.test(q))
    return res.sendStatus(400);

  res.sendStatus(200);
});

Why Node.js amplifies ReDoS impact

A synchronous regular-expression match runs on the JavaScript thread handling callbacks in a Node.js process. If a pattern takes a long time on a near-match or failed input, that event loop cannot run other callbacks or advance requests until matching returns. Worker threads, multiple processes, or replicas may preserve some capacity, but each affected process can still stall.

The impact depends on reachability, pattern complexity, input limits, and deployment topology. An attacker must reach the vulnerable match with input that triggers its expensive path. Treat this as an availability risk to the affected process; whether the whole service becomes unavailable depends on its workers, replicas, routing, and health checks.

A real npm case: CVE-2026-83606 in xmldom

The reviewed advisory for @xmldom/xmldom reports CWE-1333 in processing-instruction parsing: the vulnerable grammar lets a greedy whitespace group and a lazy data group both consume whitespace. When the closing ?> is absent, the parser retries many partitions and takes quadratic time. Versions 0.9.0-beta.9 through 0.9.10 are affected; 0.9.11 fixes the issue by preventing the separator from handing whitespace back to the data group. The advisory says the issue is specific to the scoped 0.9.x path; it does not identify the 0.8.x or unscoped package as affected.

Dependency scanning helps, but it is not a regex proof

npm audit reports known advisories matched to dependencies in the project tree; it does not analyze every regular expression in your source or discover unpublished ReDoS flaws. Keep direct and transitive dependencies patched, review advisories for affected call paths, and separately inspect patterns that process attacker-controlled text.

npm audit

Audit output covers known advisories, not every regex risk. Review the report in the context of your deployment, and separately assess whether untrusted input can reach a costly match and whether its size is bounded.

FAQ

Can I set a timeout on a JavaScript regex?

JavaScript RegExp has no per-match timeout option. Prefer a simple pattern and bound input before matching. If complex matching is required, isolate it in a worker or child process with an enforceable termination deadline; this limits impact but does not make the pattern efficient.

Does this affect browser JavaScript too?

Yes. A pathological synchronous match can freeze the page’s main thread until it returns, blocking UI work. Bound input and simplify the pattern; avoid running expensive matches on each keystroke.

Is new RegExp(userInput) safe for search?

Treat user-supplied patterns as executable input to a potentially costly matcher. Do not accept arbitrary patterns on a server without strict limits and isolation. If users only need literal search, escape input as a regex literal or use string-search APIs; escaping prevents syntax changes but does not substitute for an input-size limit.

References and remediation

See also What is ReDoS (catastrophic backtracking)?