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

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

CVE-2026-102278 is a denial of service vulnerability in the brace-expansion library that causes stack exhaustion through deeply nested brace groups. This post explains its technical details, affected versions, and mitigation steps.

Published:

CVE-2026-102278 Overview

CVE-2026-102278 is an uncontrolled recursion vulnerability in the brace-expansion npm library, a widely used dependency for glob and pattern expansion in the Node.js ecosystem. The expand_() function recurses once per level of brace nesting when processing comma-member and single-set expansions. Attackers supplying deeply nested brace groups such as {{{...a,b...}}} can exhaust the native call stack before output-length limits engage, terminating the Node.js process. The flaw is fixed in versions 1.1.20, 2.1.6, 3.0.8, and 5.0.11. The issue is classified as [CWE-400] Uncontrolled Resource Consumption.

Critical Impact

An unauthenticated attacker can crash a Node.js process by submitting roughly 6KB of nested brace input, producing a process-terminating denial-of-service condition.

Affected Products

  • brace-expansion versions prior to 1.1.20 (1.x branch)
  • brace-expansion versions prior to 2.1.6 and 3.0.8 (2.x/3.x branches)
  • brace-expansion versions prior to 5.0.11 (5.x branch)

Discovery Timeline

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

Technical Details for CVE-2026-102278

Vulnerability Analysis

The brace-expansion library generates arbitrary strings that share a common prefix and suffix, following Bash-style brace expansion semantics. The vulnerability lives in expand_(), the internal function responsible for expanding parsed brace groups. Two expansion sites recurse without bounding nesting depth: comma-member expansion and single-set re-wrapping.

A prior fix for CVE-2026-14257 made the tail of the expansion iterative, recursing only on m.post for chained groups. That change did not address recursion driven by nesting depth. As documented in the patch, approximately 3,100 levels of {{{...a,b...}}}—only around 6KB of input—are sufficient to exhaust the native V8 stack and terminate the host Node.js process.

The fix introduces an EXPANSION_MAX_DEPTH constant of 1000, bounding parser recursion far above any realistic pattern yet well below the depth at which the native stack fails.

Root Cause

The root cause is uncontrolled recursion [CWE-400] in expand_(). The parser followed brace nesting depth-first without any depth ceiling, complementing an existing EXPANSION_MAX_LENGTH output limit that could not fire early enough to prevent stack exhaustion.

Attack Vector

Exploitation requires the attacker to submit an untrusted brace-expansion pattern to any application that passes user input into brace-expansion or a downstream consumer such as minimatch, glob, or configuration loaders. No authentication or user interaction is required, and the attack is remote over the network wherever such input surfaces are exposed.

javascript
// Security patch in index.js (commit 1efee7c) - adds EXPANSION_MAX_DEPTH bound
// characters) so legitimate input is unaffected.
var EXPANSION_MAX_LENGTH = 4000000

// `expand` recurses once per level of brace *nesting* - both when expanding a
// set's comma members and when re-wrapping a set whose body is a single part.
// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one
// level per chained group), which left nesting depth unbounded: about 3,100
// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack
// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser
// will follow nesting. It sits far above any realistic pattern and well below
// the depth at which the stack runs out.
var EXPANSION_MAX_DEPTH = 1000

function numeric(str) {
  return parseInt(str, 10) == str
    ? parseInt(str, 10)

Source: GitHub Commit 1efee7c

Detection Methods for CVE-2026-102278

Indicators of Compromise

  • Unexpected Node.js process terminations with RangeError: Maximum call stack size exceeded messages referencing expand_ or brace-expansion frames.
  • Repeated worker or service restarts correlated with inbound requests containing long runs of { characters.
  • HTTP request bodies, query parameters, or job payloads containing dense sequences of unmatched or deeply nested brace tokens.

Detection Strategies

  • Inventory Node.js dependency trees with npm ls brace-expansion and flag installations resolving to versions below 1.1.20, 2.1.6, 3.0.8, or 5.0.11.
  • Add input-validation rules at ingress that reject patterns exceeding a reasonable brace-nesting depth before they reach expansion routines.
  • Correlate application crash logs with request telemetry to identify DoS attempts targeting glob or pattern-matching endpoints.

Monitoring Recommendations

  • Monitor process supervisor logs (systemd, pm2, Kubernetes) for abnormal Node.js exit codes tied to stack overflow signatures.
  • Alert on spikes in request payloads containing high densities of { and , characters at API gateways or WAF layers.
  • Track dependency drift with software composition analysis to detect reintroduction of vulnerable brace-expansion versions during builds.

How to Mitigate CVE-2026-102278

Immediate Actions Required

  • Upgrade brace-expansion to 1.1.20, 2.1.6, 3.0.8, or 5.0.11 depending on the branch in use across your dependency tree.
  • Rebuild and redeploy Node.js services after upgrading, ensuring lockfiles resolve to the patched versions rather than cached vulnerable copies.
  • Audit downstream dependencies such as minimatch and glob that transitively pull in brace-expansion and pin them to versions with the fixed dependency.

Patch Information

The maintainers published fixes across four release lines. Reference GitHub Security Advisory GHSA-qhr7-859c-m2p7 for advisory details, and the patch commits 1efee7c, 935d78f, and de84f14 for the code changes introducing EXPANSION_MAX_DEPTH.

Workarounds

  • Reject or truncate untrusted input containing more than a small number of consecutive { characters before passing it to any expansion routine.
  • Run pattern expansion inside isolated worker threads or child processes so that a stack exhaustion does not terminate the primary service.
  • Apply request-size and character-class limits at the WAF or API gateway to constrain the maximum brace-nesting depth reachable by external callers.
bash
# Upgrade brace-expansion across all resolved versions in the dependency tree
npm update brace-expansion

# Verify installed versions meet or exceed the patched releases
npm ls brace-expansion

# Force resolution to patched versions when transitively pulled in
npm install brace-expansion@^5.0.11

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.