Aug 3, 2026·7 min read·371 visits
A resource exhaustion vulnerability in the brace-expansion library permits unauthenticated remote attackers to trigger process termination via heap memory exhaustion or lock the Node.js event loop by supplying crafted nested brace structures.
CVE-2026-69152 is a high-severity Denial of Service (DoS) vulnerability in brace-expansion that allows remote, unauthenticated attackers to cause a process crash or infinite thread-blocking condition. The vulnerability stems from a complete mitigation bypass of the security checks implemented for CVE-2026-14257.
The brace-expansion library is a standard dependency in the Node.js ecosystem, commonly used to expand shell-style brace patterns like file{1..3}.txt into list arrays. This utility is critical for file path globbing, pattern matching, and script processing workflows. Because the parsing engine handles raw strings, it frequently encounters untrusted inputs from CLI utilities, configuration files, or HTTP query parameters, establishing an accessible remote attack surface.
This vulnerability is classified under CWE-400 (Uncontrolled Resource Consumption) and CWE-770 (Allocation of Resources Without Limits or Throttling). It serves as a direct mitigation bypass of the fixes introduced for CVE-2026-14257. While the previous patch successfully constrained the final merged accumulator string and execution result counts, it failed to bound intermediate calculations, leaving the parsing engine vulnerable to excessive memory allocation and CPU starvation.
Attackers can exploit this structural omission by supplying carefully structured string sequences that generate highly nested intermediate states. These states bypass downstream safety barriers, leading to either Out-of-Memory (OOM) termination of the Node.js process or lockup of the single-threaded runtime.
The core vulnerability lies in the structural separation of parsing phases within the library. The parser processes input configurations in isolated recursion steps, returning intermediary arrays before merging them into a final output array. The initial defensive checks implemented for CVE-2026-14257 only limited the final aggregated result count and characters inside the combine() function.
The first bypass vector targets comma-separated alternative structures such as {alt1,alt2,alt3,...}. During processing, the library recursively calls expand() for each nested branch, enforcing the static maxLength limit separately on each individual branch. The parser then aggregates the results into a single flat array using values.push.apply(). Because there was no running global accumulator check during this assembly, an attacker can cascade $N$ nested branches, each staying just below the threshold, resulting in a total size that scales to $N \times \text{maxLength}$, exceeding the available Node.js heap.
The second bypass vector occurs within the expandSequence() sequence generator when handling padded ranges such as {00000...0001..100000}. This component was bound only by the maximum result count, ignoring string length boundaries. Although V8 uses efficient cons-strings internally to minimize memory footprint during generation, formatting each padded range requires quadratic time complexity relative to the width and size of the range, resulting in a thread-blocking lockup.
To understand the mechanical differences, we can contrast the vulnerable logic with the fixed implementation. In unpatched versions, the sequence generator lacked tracking of intermediate lengths and directly processed large spans. The patch integrates maxLength checks inside the generation loop to break early if size thresholds are exceeded.
// Sequence Generation Fix
function expandSequence(
body: string,
isAlphaSequence: boolean,
max: number,
+ maxLength: number, // Track current character limit constraints
): string[] {
...
const pad = n.some(isPadded)
+ let length = 0
for (let i = x; test(i, y) && N.length < max; i += incr) {
let c
...
+ // Validate if adding next element exceeds limit
+ if (length + c.length > maxLength) break
N.push(c)
+ length += c.length
}
return N
}Similarly, in the comma alternative processor expand_, the engine previously pushed items without validating running bounds. The patched version implements a running budget check valuesLength and executes an early loop break when the limit is breached, preventing excessive heap allocation.
// Alternative Expansion Logic Fix
values = []
- for (let j = 0; j < n.length; j++) {
- values.push.apply(values, expand_(n[j] as string, max, maxLength, false))
+ let valuesLength = 0
+ outer: for (let j = 0; j < n.length; j++) {
+ const expanded = expand_(n[j] as string, max, maxLength, false)
+ for (let k = 0; k < expanded.length; k++) {
+ const v = expanded[k] as string
+ if (dropsEmpties && !v) continue
+ // Enforce running budget validation
+ if (values.length >= max || valuesLength + v.length > maxLength) {
+ break outer
+ }
+ values.push(v)
+ valuesLength += v.length
+ }
}Exploitation of CVE-2026-69152 requires no privileges or complex environment variables, as the parser operates entirely on standard string inputs. In applications where user input is directly expanded—such as router parameters, search fields, or directory parsers—an attacker can pass malicious payloads directly.
The first attack pattern targets the comma array heap exhaustion. By chaining multiple nested sequences, the engine is forced to allocate extensive intermediate arrays, causing a process crash due to uncatchable out-of-memory errors.
// Payload A: Memory Exhaustion Proof-of-Concept
const expand = require('brace-expansion');
const alt = '{1..5}';
const payload = '{' + Array(1000).fill(alt).join(',') + '}';
// Triggers heap out-of-memory crash
expand(payload, { maxLength: 50 }); The second pattern targets the sequence pad generator. By specifying extremely wide leading zero paddings, the application CPU is saturated attempting to compute and pad strings, blocking the execution thread indefinitely.
// Payload B: CPU Thread Blocking Proof-of-Concept
const expand = require('brace-expansion');
const payload = '{' + '0'.repeat(400000) + '1..100000}';
// Locks the Node.js event loop
expand(payload);The patches implemented in versions 1.1.18, 2.1.4, 3.0.6, and 5.0.9 effectively mitigate the primary out-of-memory and CPU loop-locking conditions. By enforcing limits on intermediate string sizes and sequences, the library protects runtime stability. However, security architects must consider the implications of the remediation design.
The engine now uses silent truncation when a boundary is hit, halting expansion processing rather than raising an explicit error exception. In downstream applications that rely on full expansion for input validation or policy rules—such as access control list parsing or path filters—silent truncation could lead to incomplete validation checks, introducing logical bypasses.
Additionally, in environments where max defaults to Infinity and empty strings are generated (such as {,}{,}{,} chains where dropsEmpties resolves to false), the tracking variable valuesLength remains unchanged because empty strings have a length of zero. While these arrays contain lightweight entries, extremely deep configurations can still lead to extensive array allocations, representing a vector for minor heap bloat.
The most effective path to remediation is upgrading to the patched package versions across all active projects. For applications unable to update dependencies immediately, input length limits should be implemented as a temporary defense. Limiting external inputs to a maximum size (such as 256 characters) prevents the construction of nested structures.
Applications should avoid executing potentially intensive utility operations on the primary thread. Running parse operations inside worker threads or sandboxed processes prevents any potential thread blocking from affecting the main application logic.
Intrusion detection rules should scan incoming query parameters and payloads for dense nested braces or highly padded sequence patterns. Signatures matching recursive sequences can help flag and drop malicious inputs before they reach the execution engine.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
brace-expansion Julian Gruber | < 1.1.18 | 1.1.18 |
brace-expansion Julian Gruber | >= 2.0.0, < 2.1.4 | 2.1.4 |
brace-expansion Julian Gruber | >= 3.0.0, < 3.0.6 | 3.0.6 |
brace-expansion Julian Gruber | >= 4.0.0, < 5.0.9 | 5.0.9 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400, CWE-770 |
| Attack Vector | Network |
| CVSS Score | 7.5 |
| EPSS Score | Not available |
| Impact | Denial of Service (Availability) |
| Exploit Status | Proof of Concept (PoC) available |
| KEV Status | Not listed |
The software does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.