CVE-2026-13149: brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups
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:
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 |
References
- github.com/advisories/GHSA-3jxr-9vmj-r5cp
- github.com/juliangruber/brace-expansion/commit/835d6be91201122d9adffb0c0c8c094189ace265
- github.com/juliangruber/brace-expansion/commit/c7e33ec13ac1a684c116720843ce24e208611754
- github.com/juliangruber/brace-expansion/commit/d74e63030c012e3b7ae81657b8d665619cd51b95
- github.com/juliangruber/brace-expansion/pull/122
- github.com/juliangruber/brace-expansion/pull/123
- github.com/juliangruber/brace-expansion/releases/tag/v1.1.16
- github.com/juliangruber/brace-expansion/releases/tag/v2.1.2
- github.com/juliangruber/brace-expansion/releases/tag/v5.0.7
- github.com/juliangruber/brace-expansion/security/advisories/GHSA-3jxr-9vmj-r5cp
- nvd.nist.gov/vuln/detail/CVE-2026-13149
- www.npmjs.com/package/brace-expansion
Code Behaviors & Features
Detect and mitigate CVE-2026-13149 with GitLab Dependency Scanning
Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →