Skip to main content
Vulnerability Database/CVE-2026-102277

CVE-2026-102277: brace-expansion Library DOS Vulnerability

CVE-2026-102277 is a denial of service vulnerability in the brace-expansion library that causes quadratic CPU time and memory pressure, blocking the Node.js event loop. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Published:

CVE-2026-102277 Overview

CVE-2026-102277 is a denial of service vulnerability in the brace-expansion Node.js library maintained by Julian Gruber. The expand function processes untrusted {a},b}-shaped patterns by restarting its scan once for every trailing closing brace. Each restart operates on a working string that grows by one escClose sentinel per pass, producing quadratic CPU time and memory pressure. Attackers who supply crafted input can block the Node.js event loop for extended periods. The issue affects versions prior to 1.1.21, 2.1.7, 3.0.9, and 5.0.12, and is tracked under [CWE-400] Uncontrolled Resource Consumption.

Critical Impact

A single 128KB input of the form '{a}' + '}'.repeat(n) + ',z}' blocked the Node.js event loop for 27 seconds while producing only two expansion results.

Affected Products

  • brace-expansion versions prior to 1.1.21
  • brace-expansion versions prior to 2.1.7 and 3.0.9
  • brace-expansion versions prior to 5.0.12

Discovery Timeline

  • 2026-09-28 - CVE-2026-102277 published to NVD
  • 2026-09-30 - Last updated in NVD database

Technical Details for CVE-2026-102277

Vulnerability Analysis

The brace-expansion library implements a Bash compatibility quirk where a brace group followed by a comma set still expands (for example, {a},b}). The parser handles this construct by rewriting the input string and restarting the scan, absorbing one } per pass. When an attacker supplies input containing n trailing closing braces, the parser performs n full passes over the input.

Because the working string grows by one escClose sentinel on each pass, the total work scales quadratically with n. The sentinel itself is roughly 26 bytes, adding a large constant factor. The result is high CPU consumption and elevated memory pressure, both of which stall the Node.js event loop and starve concurrent request handling.

The process eventually completes and recovers, which classifies the impact as a recoverable CPU denial of service rather than a crash or resource-permanent condition.

Root Cause

The root cause is missing bounds on the number of parser rewrites. The expand function had no upper limit on how many times its scan could restart, so pathological inputs with many trailing } characters drove worst-case quadratic behavior. Patched versions introduce an EXPANSION_MAX_REWRITES constant that caps rewrite iterations at 1000, which is well above the handful required by legitimate Bash-style input.

Attack Vector

Exploitation requires only that an attacker supply untrusted input to code that calls brace-expansion. This library is a common transitive dependency of minimatch, glob, and other tooling used in HTTP servers, build systems, CLI utilities, and log processors. No authentication or user interaction is required when the vulnerable code is reachable over the network. Any endpoint that expands user-controlled glob or pattern strings is a candidate attack surface.

javascript
// Security patch adding a rewrite bound in index.js
// the depth at which the stack runs out.
var EXPANSION_MAX_DEPTH = 1000

// Bash keeps a quirk where a brace group followed by a comma set still expands
// (`{a},b}`). The parser implements it by rewriting the string and restarting
// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`
// full passes over a string that itself grows by one `escClose` sentinel each
// time - quadratic in `n`, with a ~26x constant from the sentinel's length.
// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27
// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many
// times the scan may restart. Real `{a},b}` input needs a handful.
var EXPANSION_MAX_REWRITES = 1000

function numeric(str) {
  return parseInt(str, 10) == str
    ? parseInt(str, 10)
// Source: https://github.com/juliangruber/brace-expansion/commit/bdff773f98e5988616b7039cc9b508df5d640b22

Detection Methods for CVE-2026-102277

Indicators of Compromise

  • Elevated Node.js process CPU usage sustained for several seconds while serving small requests.
  • Application logs showing prolonged event-loop stalls or delayed timers on endpoints that accept pattern strings.
  • HTTP request bodies or query parameters containing repeated } characters in {a},b}-shaped constructs.
  • Dependency manifests (package.json, package-lock.json, yarn.lock) resolving brace-expansion to versions below 1.1.21, 2.1.7, 3.0.9, or 5.0.12.

Detection Strategies

  • Run npm ls brace-expansion across projects to enumerate direct and transitive versions in use.
  • Use Software Composition Analysis (SCA) tools to flag vulnerable brace-expansion ranges against advisory GHSA-q2hr-2g5m-vwhr.
  • Add application-level metrics for event-loop lag (for example, perf_hooks.monitorEventLoopDelay) and alert on spikes correlated with pattern-processing endpoints.

Monitoring Recommendations

  • Monitor request latency and Node.js event-loop delay percentiles on services that call minimatch, glob, or other brace-expansion consumers.
  • Alert on inputs whose length or brace-character ratio exceeds thresholds appropriate for legitimate glob usage.
  • Track dependency drift in CI so new builds cannot regress to vulnerable brace-expansion versions.

How to Mitigate CVE-2026-102277

Immediate Actions Required

  • Upgrade brace-expansion to 1.1.21, 2.1.7, 3.0.9, or 5.0.12 depending on the major version in use.
  • Refresh lockfiles and rebuild container images so transitive dependencies pull the patched releases.
  • Enforce request-size limits and reject unusually long pattern inputs on external-facing endpoints.

Patch Information

The fix bounds parser rewrites through the new EXPANSION_MAX_REWRITES = 1000 constant. See the upstream commits 33a5ef17, bdff773f, c55e67d8, and ffdfa3e3 for the complete change set across supported release lines.

Workarounds

  • Validate untrusted input before passing it to any brace-expansion consumer, rejecting strings with excessive } characters.
  • Cap the maximum accepted input size for glob or pattern parameters at values well below 128KB.
  • Isolate pattern-processing work in a worker thread or child process with a strict wall-clock timeout so a stall cannot block the main event loop.
bash
# Upgrade brace-expansion across a Node.js project
npm install brace-expansion@^2.1.7
npm dedupe
npm ls brace-expansion

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.