CVE-2026-13149: High severity npm brace-expansion vulnerability
Summary brace-expansion's expand() exhibits exponential-time - O(2ⁿ) - behavior in the number of consecutive non-expanding {} groups. A short, all-ASCII input (~90 bytes/30 groups) blocks the calling thread for minutes; a slightly longer input hangs it effectively indefinitely. Because the dominant consumers run on Node's single-threaded event loop, one small input can fully stall a worker/process.
In expand, post is computed unconditionally at the top of the function, before the early-return branches that don't use it: js const post = m.post.length ? expand(m.post, max, false) : ['']; // always recurses ... if (!isSequence && !isOptions) { if (m.post.match(/,(?!,).\}/)) { str = m.pre + '{' + m.body + escClose + m.post; return expand(str, max, true); // restart — post discarded } return [str]; }
For input like a{},{},…, the first {} is non-expanding, so control reaches the {a},b} rewrite branch - but expand has already recursed into post over the entire remaining tail, only to throw the result away. Each level therefore spawns two recursive expansions over essentially the same remaining work: T(n) = 2·T(n−1) ⇒ O(2ⁿ).
The max option does not mitigate this: max only bounds the output-building loops; neither the post recursion nor the rewrite recursion consults it. Measured on 5.0.6:
| groups (n) | input bytes | time | |---|---|---| | 20 | 60 | 130 ms | | 24 | 72 | 1.9 s | | 26 | 78 | 7.8 s | | 30 (PoC) | 90 | ~2 min |
Proof of concept js const { expand } = require('brace-expansion'); // 30 non-expanding groups, ~90 bytes — blocks for minutes: expand('a{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}');
Impact
Any application that passes attacker-influenced strings to brace-expansion.expand() - directly or transitively via minimatch/glob brace patterns - can be driven into a multi-minute-to-indefinite CPU hang by a tiny request, denying service on that thread/process.
Remediation
Upgrade to a patched release. The fix: 1. Defers computing post until after the early-return branches (and computes it locally in the $-suffix branch), so post is only expanded when a brace set actually expands and the value is used. This alone removes the exponential. 1. Converts the {a},b} rewrite from recursion to an in-function loop, so a long run of rewrites cannot grow the call stack.
Verified: the PoC drops from ~2 min to 0.55 ms, 5,000 groups complete in ~344 ms, and output is identical to 5.0.6 across a behavioral-equivalence suite (sequences, padding, $-prefix, a{},b}c, {},a}b, x{{a,b}}y, etc.). Post-fix complexity is ~O(n²) on this input class - acceptable for the security fix; a linear rewrite can be a non-urgent follow-up.
If immediate upgrade isn't possible, avoid passing untrusted input to expand() / glob brace patterns, or run such expansion under a timeout/worker.
Other sources
brace-expansion through 5.0.6 is vulnerable to denial of service. The expand() function exhibits exponential-time complexity in the number of consecutive non-expanding '{}' brace groups. An attacker who passes a crafted string to expand(), directly or transitively, can cause significant CPU consumption and event-loop blocking. The max option does not mitigate this, as it bounds the output size rather than the recursion work.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/brace-expansionto a version that resolves this vulnerability.Fixed in 2.1.2 - Upgrade
Upgrade
npm/brace-expansionto a version that resolves this vulnerability.Fixed in 1.1.16 - Upgrade
Upgrade
npm/brace-expansionto a version that resolves this vulnerability.Fixed in 5.0.7 - Upgrade
Upgrade
brace-expansion (brace-expansion.expand()/brace-expansion.expand_)to a version that resolves this vulnerability.Fixed in 5.0.6
Event History
Frequently Asked Questions
What is the severity of CVE-2026-13149?
The severity of CVE-2026-13149 is rated high with a score of 7.7.
What vulnerabilities are associated with CVE-2026-13149?
CVE-2026-13149 is associated with a denial of service vulnerability due to exponential-time complexity in the expand() function.
How do I fix CVE-2026-13149?
To fix CVE-2026-13149, update to the latest version of brace-expansion that addresses this denial of service issue.
What software is affected by CVE-2026-13149?
The software affected by CVE-2026-13149 is brace-expansion, specifically versions through 5.0.6.
What impact does CVE-2026-13149 have on systems?
CVE-2026-13149 allows an attacker to exploit the brace-expansion function, potentially causing significant CPU consumption and denial of service.