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-102277

CVE-2026-102277: Denial of Service via Quadratic Algorithmic Complexity in brace-expansion

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 30, 2026·7 min read·51 visits

Executive Summary (TL;DR)

The brace-expansion JavaScript library suffers from an O(N^2) quadratic complexity vulnerability when parsing legacy {a},b}-shaped structures with many trailing braces. This allows remote attackers to trigger a Denial of Service by blocking the single-threaded Node.js event loop.

An uncontrolled resource consumption vulnerability exists in the brace-expansion JavaScript library. Due to an algorithmic flaw in parsing a legacy Bash-compatibility quirk involving {a},b}-shaped expansion structures, untrusted inputs containing many trailing closing braces trigger successive full-input rescans. This behavior yields quadratic CPU time complexity and high memory overhead, allowing remote, unauthenticated attackers to cause a Denial of Service (DoS) by blocking the single-threaded Node.js event loop.

Vulnerability Overview and Context

The brace-expansion JavaScript library is a widely utilized package designed to perform shell-like brace expansion, mirroring the behavior found in shells such as sh and bash. It is a foundational utility used extensively in pattern matching and file expansion within Node.js ecosystems, often serving as a dependency for libraries like minimatch and glob.

The vulnerability is classified under CWE-400 (Uncontrolled Resource Consumption) and CWE-407 (Inefficient Algorithmic Complexity). It manifests when the parser attempts to resolve a legacy compatibility quirk. When processing a specific structure containing a sequence of trailing closing braces and a trailing comma set, the parsing state machine falls back to an inefficient iterative rewriting scheme.

An attacker capable of submitting arbitrary strings to any application interface that processes inputs via brace-expansion can exploit this flaw. Because Node.js is single-threaded, blocking the event loop with this computationally intensive processing loop prevents the runtime from handling concurrent network connections, leading to application-wide denial of service.

Root Cause Analysis

Bash retains a legacy behavior where a brace group followed by a comma set expansions despite not forming a standard option or sequence set. For example, the expression {a},b} expands into a} and b. To replicate this quirk, the brace-expansion parser identifies potential {a},b}-shaped patterns, performs an in-place string modification, and restarts the scanner loop from the beginning of the string.

When an attacker provides a payload consisting of a single valid brace group, followed by a large number of trailing closing braces, and a terminating comma set (such as '{a}' + '}'.repeat(N) + ',z}'), the parser becomes trapped in a recursive-like loop. On the first pass, the parser detects the group {a}. Because the substring after this group contains a comma and a closing brace, it matches the legacy pattern, replaces the first closing brace with an escaped sentinel string (escClose), and restarts the scan.

On the subsequent pass, the parser scans from the beginning. It bypasses the previously escaped brace and treats the next literal trailing closing brace as the group terminator. This second brace is rewritten, and the scan restarts again. This process repeats for every single trailing closing brace in the input string.

This behavior has severe performance implications. For an input with N trailing braces, the parser performs N complete rescans of the entire string, resulting in quadratic time complexity ($O(N^2)$). Furthermore, because each rewrite replaces a single-byte closing brace with a multi-byte escClose sentinel string (approximately 25 characters), the size of the processing string expands linearly, creating significant heap allocation overhead and garbage collection pressure.

Source Code Walkthrough

The vulnerability lies within the core parsing routine, specifically inside the nested matching loop. Before the patch, the parser evaluated the legacy Bash pattern and triggered an unrestricted continuation loop without tracking iteration depth or frequency.

// Vulnerable code pattern
const isOptions = m.body.indexOf(',') >= 0
if (!isSequence && !isOptions) {
  // Pattern identified as {a},b}
  if (m.post.match(/,(?!,).*\}/)) {
    str = m.pre + '{' + m.body + escClose + m.post
    isTop = true
    continue // Scan is restarted from the beginning without a limit
  }
}

The official remediation introduces EXPANSION_MAX_REWRITES to bound the scan restarts. Below is the annotated patched code structure demonstrating the restriction placed on loop iterations:

// Patched code pattern
export const EXPANSION_MAX_REWRITES = 1000
 
function expand (str, max, maxLength, maxDepth, depth, maxRewrites, isTop) {
  let rewrites = 0
  
  // ... inner parser loop ...
  
    const isOptions = m.body.indexOf(',') >= 0
    if (!isSequence && !isOptions) {
      // Check the rewrite limit before attempting legacy modification
      if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) {
        rewrites++
        str = m.pre + '{' + m.body + escClose + m.post
        isTop = true
        continue // Restarts scan, but capped at 1000 iterations
      }
    }

By capping the iteration count, the parser prevents unbounded execution on malicious inputs. Once the threshold of 1000 rewrites is exceeded, the parser ceases rewriting, exits the loop, and processes the remaining segment as a literal string.

Exploitation and Proof-of-Concept

To exploit this vulnerability, an attacker must submit a structured payload containing a leading simple brace group, a high count of consecutive closing braces, and a final comma set. Because the payload relies solely on common characters, it easily bypasses standard sanitization mechanisms that only look for malicious command sequences or script tags.

const expand = require('brace-expansion');
 
// Construct a payload containing 80,000 trailing braces
const n = 80000;
const payload = '{a}' + '}'.repeat(n) + ',z}';
 
console.log(`[+] Running expansion with ${n} trailing braces...`);
const startTime = performance.now();
 
// Trigger the vulnerable parsing loop
const result = expand(payload);
 
const endTime = performance.now();
console.log(`[+] Completed in ${(endTime - startTime).toFixed(2)} ms`);

When executed on an unpatched environment, the single-threaded Node.js event loop blocks entirely. During this execution window, the application is unable to process incoming requests, complete asynchronous database queries, or respond to health check probes. This leads to connection timeouts and service unresponsiveness.

Patch Analysis and Residual Risks

The mitigation successfully blocks the infinite rewriting path by enforcing EXPANSION_MAX_REWRITES = 1000. However, security engineers should consider the architectural implications of how the state is tracked.

The rewrites variable is scoped locally within each execution context of the recursive expand function. When processing nested expansion sequences, each nested call receives its own independent allocation of 1000 rewrites. An attacker can theoretically design a multi-layered nested structure to bypass the 1000-rewrite ceiling globally, though the total impact is bounded by the separate EXPANSION_MAX_DEPTH (1000) and EXPANSION_MAX_LENGTH (4,000,000) limits.

Another residual behavior is that when the rewrite limit is reached, the library silently stops expanding and treats the remaining portion literally. If downstream components expect fully expanded arrays for access control or command parsing, this behavior can introduce parser differential issues where the application logic processes the literal string representation differently than intended.

Remediation and Defensive Guidance

The primary remediation step is to upgrade the brace-expansion dependency to a safe release version. The fix has been backported across all active branches to maintain backward compatibility.

# Verify dependency status and upgrade paths
npm audit
 
# Upgrade brace-expansion to the latest patched version
npm install brace-expansion@latest

If immediate dependency updates are not possible, deploy a Web Application Firewall (WAF) rule to block incoming request parameters containing repetitive closing braces. The following pattern matches payloads trying to exploit this behavior:

\{[^}]+\}[}]{10,}.*,

This regex detects the necessary sequence of a valid brace group, followed by ten or more consecutive closing braces, followed by a trailing comma, allowing security teams to drop matching requests at the edge.

Fix Analysis (4)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
EPSS Probability
0.30%
Top 79% most exploited

Affected Systems

Applications utilizing brace-expansion in Node.js environments for path or glob matchingDownstream packages like minimatch and glob utilizing vulnerable versions of brace-expansion

Affected Versions Detail

Product
Affected Versions
Fixed Version
brace-expansion
Julian Gruber
< 1.1.211.1.21
brace-expansion
Julian Gruber
>= 2.0.0, < 2.1.72.1.7
brace-expansion
Julian Gruber
>= 3.0.0, < 3.0.93.0.9
brace-expansion
Julian Gruber
>= 4.0.0, < 5.0.125.0.12
AttributeDetail
CWE IDCWE-400, CWE-407
Attack VectorNetwork (Remote)
CVSS v3.1 Score5.3
EPSS Score0.00301
ImpactAvailability (Denial of Service)
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.003Endpoint Denial of Service: Application Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

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

Vulnerability Timeline

Patches developed and committed by Julian Gruber
2026-09-14
GitHub Security Advisory GHSA-q2hr-2g5m-vwhr published
2026-09-28
CVE-2026-102277 assigned and published
2026-09-28
NVD database updated with analyzed metrics and CVSS vector details
2026-09-29

References & Sources

  • [1]GitHub Security Advisory (GHSA-q2hr-2g5m-vwhr)
  • [2]NVD Vulnerability Details Page
  • [3]CVE.org Record

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

•3 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
0 views•10 min read
•about 1 hour 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 2 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 3 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 4 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 5 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