Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessCraft malicious brace pattern string
-
DeliverySubmit via exposed input channel
-
Exploitexpand_() builds unbounded intermediate arrays
-
Executioncombine() maxLength guard triggers too late
-
PersistV8 heap exhausted
-
ImpactNode.js process terminates with fatal OOM
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V2 - Validation and Business Logic Resource consumption limits
MITRE ATT&CK
1 technique across 1 tactic: Impact The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires that the target application passes attacker-controlled string data to |
| Impact | The vendor-assigned CVSS 3.1 score of 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) is consistent with the technical evidence: network reachability, low attack complexity, and no privileges required are all accurate for any application exposing brace-pattern input externally. The practical risk is elevated beyond what a mid-7 score might suggest for three independent reasons: the memory-exhaustion variant produces a fatal V8 OOM abort that bypasses try/catch entirely, making in-process resilience measures ineffective; a detailed proof-of-concept is publicly embedded in the GHSA advisory; and brace-expansion is a ubiquitous transitive dependency, meaning the blast radius extends to any Node.js application indirectly using npm, glob, or minimatch without necessarily knowing it. No EPSS score was provided and no CISA KEV listing is recorded, so widespread automated exploitation has not been confirmed - this signals targeted rather than opportunistic exploitation at present. The absence of a confidentiality or integrity impact keeps the CVSS score from reaching Critical, but the combination of published POC, uncatchable crash vector, and enormous transitive footprint makes this a genuine remediation priority rather than a theoretical high-CVSS-but-low-real-risk issue. |
| Exploit ScenarioDerived | An attacker submits a crafted ~25 KB HTTP request body containing a brace pattern composed of approximately 400 comma-separated alternatives, each embedding a padded numeric sequence (e.g., |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Aug 03, 2026
Remote denial-of-service in the brace-expansion npm library (all active version lines prior to 1.1.18, 2.1.4, 3.0.6, and 5.0.9) allows unauthenticated attackers to either crash the Node.js process via an uncatchable out-of-memory error with a ~25 KB crafted input, or stall the event loop for over two minutes with a ~400 KB padded-sequence input. Both attack paths bypass the incomplete mitigation introduced in version 5.0.8 for CVE-2026-14257, meaning applications that already patched that predecessor vulnerability remain fully exposed. Publicly available proof-of-concept code is included in the GitHub security advisory; no CISA KEV listing is present at time of analysis.
RemediationAI
Upgrade brace-expansion to the appropriate fixed release for the installed version line: 1.1.18, 2.1.4, 3.0.6, or 5.0.9. Because brace-expansion is typically installed as a transitive dependency, run npm ls brace-expansion or npm audit to identify all installed copies and the parent packages pinning them to vulnerable versions; upgrade those parent packages accordingly. Patch commits are available at https://github.com/juliangruber/brace-expansion/commit/139d015104e71433ad52a41d19467c48ecbb2c7d and https://github.com/juliangruber/brace-expansion/commit/1e30c930238d7162802d88a94189182def178dac. If immediate upgrade is not possible, the advisory recommends passing an explicitly small max and maxLength together to expand() - for example { max: 1000, maxLength: 10000 } - as a compensating control; however, note that maxLength alone was insufficient on affected versions because it was enforced per-alternative rather than cumulatively, which is the root cause of the first bug. The most reliable workaround is to avoid passing untrusted input to any function that transitively calls expand(), including glob pattern evaluation.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
brace-expansion (pkg:npm/brace-expansion) is a JavaScript library that expands Unix brace-notation patterns such as {a,b,c} and {1..5} into arrays of strings; it is a transitive dependency of npm itself, minimatch, glob, and thousands of downstream packages. CWE-400 (Uncontrolled Resource Consumption) applies through two distinct intermediate-data-structure paths inside expand_(). In the first path, each comma-separated alternative in a {a,b,...} pattern is expanded by its own recursive expand_() call, each receiving a full independent maxLength budget, and all results are concatenated into a single values array with no cumulative running total - allowing values to reach A × maxLength characters before combine() ever checks bounds. In the second path, expandSequence() accepted a max (result-count) bound but never consulted maxLength, so padded-numeric sequences of arbitrary width were fully generated before combine() discarded excess results; V8's cons-string representation kept heap flat, hiding the cost as wall-clock CPU time rather than memory pressure. Both paths were introduced by the design of the 5.0.8 fix, which guarded only the single accumulator in combine() rather than the two intermediate arrays that feed it.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Network vector and no privileges because any input channel suffices; High availability from uncatchable process crash; no confidentiality or integrity impact.
Primary rating from Vendor (https://github.com/juliangruber/brace-expansion).
CVSS VectorVendor: https://github.com/juliangruber/brace-expansion
DescriptionCVE.org
Summary
The maxLength mitigation added in 5.0.8 for GHSA-mh99-v99m-4gvg / CVE-2026-14257 is incomplete. It bounds the accumulator where results are *combined*, but not the intermediate arrays that feed it. A ~25 KB input still crashes the Node process with an uncatchable out-of-memory error, so try/catch around expand() does not help.
A second, related path in the same function lets a ~400 KB input block the event loop for over two minutes without ever exceeding the memory bound.
Details
maxLength was enforced in combine(), the single place output grows. Two arrays are built *before* combine() runs, and neither was bounded.
1. Comma alternatives accumulate without a running total (memory exhaustion)
Each alternative in {a,b,c,...} is expanded by its own recursive expand_() call, so each receives a full, independent maxLength allowance. The results were then concatenated into a single values array with no cumulative limit:
values = []
for (let j = 0; j < n.length; j++) {
values.push.apply(values, expand_(n[j], max, maxLength, false))
}
acc = combine(acc, pre, values, max, maxLength, ...)With A alternatives, values can reach A * maxLength characters before combine() gets a chance to truncate it. At the default maxLength of 4,000,000 and 400 alternatives, that is well past any default heap.
2. Padded sequences ignore maxLength while generating (CPU exhaustion)
expandSequence() was bounded by max (the result *count*) but never consulted maxLength. A padded sequence's element width follows the input, so {0...01..100000} with a wide pad generates max elements, each as wide as the input, only for combine() to discard all but a handful.
Memory stays flat here, because V8 represents the padded strings as cons-strings, which is likely why this path was not caught alongside the original issue. The cost is time: work proportional to max * width.
| pad width | input bytes | results kept | time (5.0.8) | time (patched) |
|---|---|---|---|---|
| 20,000 | 20 KB | 199 | ~7.3 s | ~20 ms |
| 100,000 | 100 KB | 39 | ~32 s | ~20 ms |
| 400,000 | 400 KB | 9 | ~124 s | ~18 ms |
Output is byte-identical before and after the fix; only the wasted work is removed.
Proof of concept
Memory exhaustion, against 5.0.8:
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
}FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
AbortedEvent-loop stall, against 5.0.8:
import { expand } from 'brace-expansion'
// ~400 KB input, returns 9 results after roughly two minutes of blocking CPU
expand('{' + '0'.repeat(400_000) + '1..100000}')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: the 5.0.8 mitigation does not cover these paths.
Patches
Both intermediate arrays are now bounded as they are built, using the same max and maxLength limits already applied in combine():
valuestracks a running result count and character length while alternatives are appended, and stops once either bound is reached.expandSequence()acceptsmaxLengthand stops generating once the sequence's own characters reach it.
As with the existing limits, output is truncated rather than allowed to grow without bound, which matches how max already behaves. The defaults sit well above any realistic expansion, so legitimate input is unaffected.
Workarounds
If upgrading is not immediately possible, avoid passing untrusted input to expand() or to glob brace patterns, or pass an explicitly small max and maxLength.
Note that a small maxLength alone was not sufficient on affected versions: it was applied per alternative rather than cumulatively, which is the root of the first issue above.
Credits
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.
Blast Radius
ecosystem impact- 1 npm packages depend on brace-expansion (1 direct, 0 indirect)
Ecosystem-wide dependent count for version 2.0.0.
Latest POC
1 PoC candidate from github (unverified)
Sign in to open the public PoC links collected for this CVE.
Executive ViewAI
Organizations using the brace-expansion npm library in production face immediate risk of service disruption through remote denial-of-service attacks requiring no authentication. Publicly available attack code eliminates technical barriers to exploitation, making this a business continuity concern that demands urgent remediation.
Vendor-released patch: versions 1.1.18, 2.1.4, 3.0.6, and 5.0.9 for respective version lines.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.
Same weakness CWE-400 – Uncontrolled Resource Consumption
View allSame technique Denial Of Service
View allVendor StatusVendor
SUSE
Severity: Important| Product | Status |
|---|---|
| SUSE Liberty Linux 10 | Fixed |
| SUSE Liberty Linux 8 | Fixed |
| SUSE Linux Enterprise Server 16.0 | Affected |
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.0 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| openSUSE Leap 16.0 | Affected |
EUVD-2026-52370
GHSA-rgw5-rvv9-x895
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB