CVE-2026-93687 Overview
CVE-2026-93687 is a stack overflow vulnerability in the braces Node.js library through version 3.0.3. The library's recursive abstract syntax tree (AST) walkers in parse.js, compile.js, and expand.js lack depth guards. Attackers can supply deeply nested brace patterns that remain under the character limit but exhaust the Node.js call stack. The process terminates with an uncaught RangeError, producing a denial-of-service condition. The flaw is tracked under CWE-674: Uncontrolled Recursion and affects any application that passes untrusted input to braces for expansion or matching.
Critical Impact
Remote, unauthenticated attackers can crash Node.js processes that parse untrusted brace patterns, disrupting availability of services that depend on braces or its consumers such as micromatch.
Affected Products
- braces npm package through version 3.0.3
- Downstream libraries that depend on braces (for example, micromatch)
- Node.js applications that pass untrusted input to affected braces APIs
Discovery Timeline
- 2026-09-18 - CVE-2026-93687 published to the National Vulnerability Database (NVD)
- 2026-09-22 - Last updated in NVD database
Technical Details for CVE-2026-93687
Vulnerability Analysis
The braces library expands Bash-style brace patterns such as {a,b,c} into arrays of strings. Expansion relies on recursive descent through an AST constructed from the input pattern. The parser, compiler, and expander each walk the tree recursively without tracking or limiting recursion depth.
When an attacker submits an input containing many nested braces such as {{{{...}}}}, each nesting level adds a stack frame during traversal. The input can stay well within any character-length validation while still producing a tree deep enough to exceed the V8 engine's call stack limit. Node.js then throws an uncaught RangeError: Maximum call stack size exceeded and terminates the worker or server process.
Because braces sits underneath widely used file-matching libraries, the vulnerability propagates into build tooling, web frameworks, and any service that accepts glob patterns from clients.
Root Cause
The root cause is uncontrolled recursion in three tree-walking routines: the parser in lib/parse.js, the compiler in lib/compile.js, and the expander in lib/expand.js. None of these functions enforce a maximum nesting depth or convert recursion to iteration.
Attack Vector
Exploitation requires no authentication and no user interaction. An attacker sends a crafted string containing deeply nested braces to any interface that forwards the value into a braces API such as braces(), braces.expand(), or braces.compile(). Common exposures include glob-based file search endpoints, configuration parsers, and log query interfaces. See the VulnCheck advisory and GitHub issue #70 for reproduction details.
Detection Methods for CVE-2026-93687
Indicators of Compromise
- Node.js process exits with RangeError: Maximum call stack size exceeded referencing frames inside braces/lib/parse.js, compile.js, or expand.js.
- Repeated worker or container restarts correlated with inbound requests containing long sequences of { or } characters.
- Application error logs showing crash-loop behavior shortly after receiving glob or pattern input from external clients.
Detection Strategies
- Inspect HTTP request bodies, query strings, and message queue payloads for pathological brace nesting depth, independent of overall length.
- Run dependency scans (npm audit, npm ls braces) across production and build environments to enumerate direct and transitive uses of braces at or below version 3.0.3.
- Correlate process termination events with the preceding request or job payload in centralized logging to identify triggering inputs.
Monitoring Recommendations
- Alert on Node.js uncaught exception telemetry that references braces module paths.
- Track unusual spikes in process restarts, container OOM-adjacent crashes, or worker respawns on services that accept user-supplied patterns.
- Feed application logs and process metrics into a centralized analytics platform so recurring crash signatures can be triaged as a single incident.
How to Mitigate CVE-2026-93687
Immediate Actions Required
- Enumerate every application that pulls in braces directly or transitively and prioritize upgrades for services exposed to untrusted input.
- Add input validation at network and application boundaries to reject strings whose brace nesting depth exceeds a small, business-appropriate threshold.
- Wrap calls into braces with try/catch and process-level uncaught exception handlers so a single malicious pattern cannot crash the entire runtime.
Patch Information
At the time of publication, the NVD entry does not list a fixed release. Monitor the micromatch/braces repository and the VulnCheck advisory for a patched version, then upgrade all direct and transitive dependencies. Rebuild container images and lockfiles after upgrading.
Workarounds
- Reject or truncate inputs whose count of { characters exceeds a safe limit (for example, 32) before invoking braces.
- Run pattern expansion inside a worker thread or child process so a RangeError crash does not take down the main service.
- Where feasible, replace calls into braces with a non-recursive matcher for untrusted input paths until a fixed release is available.
# Configuration example: enumerate braces usage and enforce a depth guard
npm ls braces
# Simple pre-validation before passing user input to braces
node -e "const s=process.argv[1]; if((s.match(/\{/g)||[]).length>32){process.exit(2)}" "$USER_PATTERN"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.