Email me

Explainer · 6 min read

Filed under Coding agents AI agents

What is ReDoS, and why did glob libraries get hit so hard in 2026?

Short answer

ReDoS (regular expression denial of service) is when a short, crafted input makes a regex take seconds, minutes or forever to fail. Backtracking engines like V8, PCRE and Python's re try every way to split the text across ambiguous groups, and that count explodes. On Node.js, one stuck match freezes the whole server.

Card: What is ReDoS? One regex, one bad input, one stuck CPU. minimatch turns each star into [^/]*?. 8 groups against 30 characters: 418 ms. 10 groups: 8.4 s. 11 groups: 33.8 s. brace-expansion: 7 advisories in 2026, 400 million downloads a week.
Each extra wildcard roughly quadruples the time a failed match takes. Card by Tensorust. Timings measured on Node 22.16, Oct 27 2026; advisories from OSV.dev.

Part of the article OpenClaw got 591 advisories. 1 in 4 top npm installs is the real hole. This page answers one question from it in depth.

On this page · 9 sections
  1. Key numbers
  2. How a regex can take forever
  3. Why Node.js takes it worst
  4. Not every DoS advisory is a regex
  5. Common misconceptions
  6. What you can do now
  7. Related
  8. FAQ
  9. Sources

TL;DR: We timed a minimatch-style regex on Node 22.16 against a 30-character string: 4 groups took 0.33 ms, 8 groups 418 ms, 10 groups 8.4 seconds, 11 groups 33.8 seconds. minimatch got 3 high-severity ReDoS advisories in February 2026, and brace-expansion got 7 DoS advisories in 2026 alone. In the week of Oct 16-22 2026, 56.4% of brace-expansion's 400 million weekly downloads were still on an affected version.

This is the cheapest denial of service there is. No botnet, no bandwidth, one string. And it hides in the most boring code in your tree: the glob matcher your build tool uses, the router that turns /users/:id into a regex. We counted the damage in our npm advisories breakdown; this page is the mechanism, and the fix you can ship today.

Key numbers

What Number Source (checked Oct 27 2026)
Regex with 8 lazy groups vs 30 chars, one failed test 418 ms Tensorust timing, Node 22.16
Same with 11 groups 33.8 s Tensorust timing, Node 22.16
minimatch ReDoS advisories, Feb 2026 3 (all high) OSV.dev
brace-expansion DoS advisories in 2026 7 OSV.dev
brace-expansion downloads on an affected version, Oct 16-22 56.4% of 400M/week Our data.csv
Official weakness id CWE-1333 MITRE CWE-1333

How a regex can take forever

A backtracking engine reads a pattern like a choose-your-own-adventure book. When a branch fails, it goes back and tries the next one. Usually there are a handful of branches. ReDoS happens when the pattern lets the same characters be claimed by many different groups.

The minimatch advisory, GHSA-3ppc-4f35-3m26, shows the exact shape. Every * in a glob compiles to [^/]*?. A pattern like ***************X*** becomes fifteen of those groups in a row, then an X. If the filename has no X, the engine has to try every way of splitting the characters across fifteen groups before it can say no. The advisory puts it at O(4^N): 15 stars, about 2 seconds; 34 stars, effectively forever.

Log-scale bars: one regex.test() call against a 30-character string with no X. 4 groups 0.33 ms, 6 groups 15.11 ms, 8 groups 418 ms, 10 groups 8.4 s, 11 groups 33.8 s. Pattern ^([^/]*?){N}X$, the shape minimatch compiles. Node 22.16 (V8) on our PC, Oct 27 2026. We stopped at 11 because 12 would have taken minutes.

You can reproduce it in ten seconds:

const s = 'a'.repeat(30);
const re = new RegExp('^' + '[^/]*?'.repeat(10) + 'X$');
console.time('redos'); re.test(s); console.timeEnd('redos'); // about 8 s

Why Node.js takes it worst

Node runs your JavaScript on one thread. While re.test() grinds, no other request, timer or health check runs. A Python or Java server with a thread pool loses one worker per bad request; a Node server loses everything. That is why a ReDoS in a library with 459 million weekly downloads (minimatch, Oct 16-22) is a real outage risk, not a footnote.

Not every DoS advisory is a regex

brace-expansion's 2026 run shows the wider family. Its 7 advisories this year carry these weakness tags: exponential expansion of consecutive {} groups (CWE-407), unbounded output length crashing the process out of memory (CWE-770), uncontrolled recursion blowing the stack (CWE-674, two advisories on Sept 29 alone), and a zero-step sequence that hangs. One, GHSA-rgw5-rvv9-x895, exists because it bypassed the mitigation for the one before it. Same lesson as ReDoS: any library that turns a short string into a big computation is an attack surface.

Bars: share of last week's npm downloads on a version with a 2026 advisory. brace-expansion 56.4%, path-to-regexp 23.0%, minimatch 21.7%. npm downloads API, Oct 16-22 2026, matched against GitHub-reviewed advisories. Tensorust count.

The fixes shipped. The installs did not move. More than half of brace-expansion's traffic is still on a vulnerable version because it sits three or four levels deep in lockfiles nobody regenerates. Who blocks the upgrade? Nobody. It is just not anyone's job, which means it can be yours.

Common misconceptions

Myth

"Only weird hand-written regexes are vulnerable."

The recordThe 2026 hits were in compiled patterns: globs (minimatch), route paths (path-to-regexp) and brace syntax. You never wrote a regex; your dependency wrote one for you from config.

Myth

"A timeout fixes it."

The recordJavaScript cannot interrupt a running regex. A request timeout fires after the event loop is free, which is after the damage. You need input limits, worker threads or a different engine.

Myth

"It is only exploitable if users can type patterns."

The recordThat is the main path for minimatch, where the pattern is the dangerous input. But path-to-regexp and many validators apply a fixed pattern to user text, and one bad fixed pattern is enough.

Myth

"Rust and Go have the same problem."

The recordThe Rust regex crate and Go's regexp use automata that guarantee linear time in the input, so catastrophic backtracking cannot happen. That is a real reason to route untrusted patterns through them, or through Google's RE2.

What you can do now

  1. Find the versions in your tree: npm ls minimatch brace-expansion path-to-regexp, then check each one with the free OSV API (our step by step guide).
  2. Upgrade or override: minimatch 3.x is fixed in 3.1.4 (each newer major has its own patch release); use overrides in package.json to force the fix into deep copies.
  3. Cap input length before any regex or glob sees it. 30 characters was enough to cost 33.8 seconds.
  4. If users supply patterns, compile them with RE2 (the re2 npm package) or move the matching into a Rust or Go service.
  5. In CI, run npm audit or osv-scanner on every lockfile change so the next advisory reaches you in hours, not years.

FAQ

What is ReDoS in simple terms?

ReDoS (regular expression denial of service) is an attack where a short, crafted input makes a regular expression take exponential or polynomial time to fail. On a single-threaded server like Node.js, one request can block every other request until the match finishes.

What causes ReDoS?

Backtracking regex engines (V8, PCRE, Python re, Java) try every way to split the input across ambiguous groups such as nested or adjacent quantifiers. When the match fails, the number of splits explodes. CWE-1333 is the official weakness id.

How long can a ReDoS take?

In our test on Node 22.16, a minimatch-style regex with 8 lazy groups took 418 ms against a 30-character string, 10 groups took 8.4 seconds and 11 groups took 33.8 seconds. The minimatch advisory GHSA-3ppc-4f35-3m26 says 34 wildcards hang effectively forever.

How do I prevent ReDoS?

Never pass user input as a pattern, cap input length, upgrade the library to the fixed version, and for user-supplied regex use a linear-time engine such as RE2, the Rust regex crate or Go's regexp, which cannot backtrack.

Is the Rust regex crate vulnerable to ReDoS?

Not to catastrophic backtracking: the Rust regex crate guarantees linear time in the input by design. Huge patterns can still be slow to compile, which is why it has size limits.

Sources

All checked October 27, 2026.

Next question

Every number on this page links to its source and was checked on Oct 27, 2026. Spot an error or a newer figure? Email matt@tensorust.com and it gets fixed.

Read next

Back to The Manual →   All articles →

Get the next one by email.

What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.

No spam, never sold. Every email has a one-click unsubscribe.

Up next

The article this answer comes fromOpenClaw got 591 advisories. 1 in 4 top npm installs is the real holeOpen-source advisories tripled in 2026 and AI tools are 15.5% of them. OpenClaw has 591, but 24.7% of top npm installs carry a fixed high-severity hole.Read it next →

Art: Nicholas Roerich, Depsang Plains (1925-26). Public domain, via Wikimedia Commons.

Get the receipts by email.

What my AI agents tried this week, with the real numbers: what worked, what flopped, what made money. One email when there is something worth reading.

No spam, never sold. Every email has a one-click unsubscribe.

Did this answer your question?

Popular in the shop

All 124 tools →

Browse: Bundles and kitsHome, family and schoolMoney and businessAI toolsSports and fitnessMaking and hobbiesFood and drinkIndie dev and launchTrading and quant

Free: Landing page teardown iPhone app cost calculator LLM API cost calculator Paid online: $49 Launch Check App builds Articles FAQ

Disagree, or have a number to add? Discuss this on The Floor →

What are people saying about this? Read and post on The Floor →