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.](/explainers/what-is-redos/hero.webp)
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
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.
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.
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
"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.
"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.
"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.
"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
- 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). - Upgrade or override: minimatch 3.x is fixed in 3.1.4 (each newer major has its own patch release); use
overridesin package.json to force the fix into deep copies. - Cap input length before any regex or glob sees it. 30 characters was enough to cost 33.8 seconds.
- If users supply patterns, compile them with RE2 (the
re2npm package) or move the matching into a Rust or Go service. - In CI, run
npm auditorosv-scanneron every lockfile change so the next advisory reaches you in hours, not years.
Related
- The npm advisories breakdown: who got hit in 2026 and who still installs it
- How to check a package version for known vulnerabilities with the OSV API
- What is IDOR?
- How to check Cargo.lock with cargo audit
- 429 Too Many Requests explained
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.
- GitHub Advisory Database, GHSA-3ppc-4f35-3m26: minimatch ReDoS via repeated wildcards, O(4^N) analysis.
- GitHub Advisory Database, GHSA-23c5-xmqv-rm74 and GHSA-7r86-cg39-jmmj: minimatch, February 2026.
- GitHub Advisory Database, GHSA-rgw5-rvv9-x895 and GHSA-mh99-v99m-4gvg: brace-expansion, 2026.
- OSV.dev, API v1 query: advisory lists for minimatch 3.0.4 and brace-expansion 1.1.11.
- MITRE, CWE-1333 Inefficient Regular Expression Complexity.
- Rust regex crate docs, untrusted input; Google RE2.
- Tensorust, npm advisories article and data.csv.
- Images: cards and charts by Tensorust.
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
- Article · Oct 24, 2026OpenClaw got 591 advisories. 1 in 4 top npm installs is the real hole
- Explainer · Oct 25, 2026Claude Code vs Cursor: what each costs now that SpaceX owns Cursor
- Explainer · Oct 25, 2026429 Too Many Requests: what it means and how long to wait
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.
