Affected Versions
| Affected | brace-expansion with unpatched brace pattern parsing (versions unknown) |
| Fixed in | unknown |
| Ecosystem | npm |
| CVE / GHSA | CVE-2026-13149 / not assigned |
| CWE | unknown |
Introduction
A critical denial-of-service vulnerability reached production through a deceptively simple API: brace-expansion, the ubiquitous npm package that converts brace patterns like file-{a,b,c}.txt into expanded arrays. The flaw lies in how consecutive brace groups compound their expansion cost—each nested or sequential brace multiplies the output size exponentially rather than additively.
This vulnerability matters because brace-expansion sits at the heart of file globbing in build tools, test runners, and development servers. When user-controlled input reaches this parser without length or complexity limits, a single HTTP request can submit a pattern that generates billions of combinations, freezing the event loop and exhausting memory.
The Vulnerability Explained
The core issue is algorithmic: brace-expansion implements brace expansion using recursive generation that creates all possible combinations. Consider this innocent-looking pattern:
{a,b}{c,d}{e,f}{g,h}{i,j}{k,l}{m,n}{o,p}{q,r}{s,t}
This produces 2^10 = 1,024 results. Double the brace groups to 20, and you hit 1,048,576 expansions. At 30 groups, you're generating over a billion strings—enough to hang a Node.js process for minutes and consume gigabytes of memory.
The vulnerable code path processes each brace group independently, then computes the Cartesian product of all results. The implementation lacks:
- Maximum expansion count limits
- Input pattern complexity scoring
- Early termination for exponential-growth patterns
An attacker exploiting CVE-2026-13149 could target any endpoint accepting glob patterns: file upload filters, build configuration APIs, or development server routes. The payload requires no special characters beyond braces and commas—making it easy to bypass naive input validation.
Real-world impact: A developer running webpack-dev-server or similar tools with live reload could have their entire development environment frozen by a single malicious WebSocket message or HTTP request containing a crafted brace pattern.
The Fix
The remediation for CVE-2026-13149 requires bounding the expansion algorithm's complexity. While the exact patched version remains unspecified, effective fixes typically implement:
- Maximum expansion limits: Abort when output would exceed a configurable threshold (commonly 10,000-100,000 results)
- Pattern complexity scoring: Reject or simplify patterns with consecutive brace groups exceeding safe depth
- Iterative expansion with early termination: Replace recursive generation with bounded iteration
For the related websocket-driver vulnerability (CVE-2026-54466) addressed in the same maintenance window, the fix was specific and verifiable:
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
- "integrity": "[hash omitted]",
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz",
+ "integrity": "[hash omitted]",
The package.json changes forced this version across all Docusaurus packages using npm's overrides mechanism:
"overrides": {
"@docusaurus/core": {
"websocket-driver": "0.7.5"
},
"@docusaurus/plugin-client-redirects": {
"websocket-driver": "0.7.5"
}
}
This ensures transitive dependencies resolve to the patched version regardless of what individual packages declare.
Key Takeaways
-
Brace expansion is not free: Every consecutive brace group multiplies cost. Any API accepting brace patterns from untrusted input must implement expansion limits before calling
brace-expansion. -
Cartesian products explode silently: 20 brace groups with 2 options each exceeds a million expansions. Developers rarely consider this when accepting "simple" glob patterns from users.
-
npm overrides are security-critical: When vulnerable packages exist deep in transitive dependency trees,
overridesinpackage.jsonis often the only practical remediation path. -
Development tools are attack surfaces:
webpack-dev-server, live reload servers, and build tools accept input that reaches pattern-matching libraries. These endpoints need the same input validation as production APIs. -
Algorithmic DoS requires algorithmic defenses: Rate limiting and request timeouts help, but the only complete fix is bounding the expensive computation itself.
How Orbis AppSec Detected This
Source: User-controlled input reaching pattern expansion APIs (brace patterns in HTTP parameters, WebSocket messages, or configuration uploads)
Sink: brace-expansion library invoked without complexity bounds on the parsed pattern
Missing control: No maximum expansion limit, no pattern complexity validation, no input length restrictions on brace group count
CWE: unknown (algorithmic complexity issues lack a specific CWE identifier)
Fix: Implement expansion result limits and pattern complexity scoring before executing brace expansion on untrusted input
Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.
Conclusion
CVE-2026-13149 exposes a fundamental tension in utility libraries: convenience versus safety. brace-expansion provides elegant, powerful pattern matching—but that power becomes a liability when exposed to adversarial input. The fix requires neither cryptographic expertise nor complex static analysis: simply bound the computation, validate the pattern complexity, and fail safely. For developers, the lesson is to audit every path where user input reaches pattern-matching libraries, no matter how "internal" the endpoint appears.