CVE-2026-93687
Executive Summary
CVE-2026-93687 is a stack overflow vulnerability in the braces npm package (through version 3.0.3) affecting recursive AST walkers that lack depth guards. Attackers who supply deeply nested brace patterns within the input character limit can exhaust the Node.js call stack, causing an uncaught RangeError that terminates the process. The vulnerability carries a CVSS score of 7.5 (High) with network attack vector and no privileges or user interaction required; availability impact is High, while confidentiality and integrity impacts are None. Any Node.js application, build pipeline, or server-side service that parses untrusted input using braces at or below version 3.0.3 is potentially affected; no patch currently exists.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
CVE-2026-93687 is classified as CWE-674: Uncontrolled Recursion. The flaw resides specifically in the recursive AST (Abstract Syntax Tree) walkers within the braces library that "lack depth guards." Braces is a widely deployed utility for expanding brace patterns (e.g., {a,b,c}) used by glob and filesystem libraries and, transitively, by many Node.js build and tooling ecosystems.
The mechanism is straightforward and class-level:
- Input surface: The library accepts string input containing brace-delimited patterns. The parser builds an AST representing nesting and alternation.
- Recursion without a depth limit: The AST walkers traverse nested structures recursively. Because no depth guard (maximum recursion depth or nesting counter) is enforced, the stack frame consumption scales linearly with nesting depth supplied by the attacker.
- Character-limit bypass: The NVD description explicitly states the attacker can supply deeply nested brace patterns "under the character limit." This means the payload does not need to be large; nesting compressively encodes deep AST structure within the string length constraint imposed by the consuming application (e.g., an input field's
maxLength, a URL parameter size limit, or a body-size limit). A relatively short string of open/close delimiters produces a disproportionately deep call stack. - Failure mode: Once the Node.js call stack is exhausted, V8 raises a
RangeError(typicallyMaximum call stack size exceeded). The description notes this manifests as an uncaughtRangeError— i.e., the exception propagates to the top of the event loop and terminates the Node.js process. This is a denial-of-service condition, not memory corruption and not remote code execution.
Attack surface: Any code path where an application passes attacker-controllable string data into braces for pattern expansion, validation, or parsing. This includes server-side HTTP handlers that accept path, glob, or template patterns; CLI tools; and CI/CD jobs that process repository-supplied pattern strings. Because braces is a transitive dependency of numerous packages, the vulnerable code may be present without the application developer explicitly importing it.
Important limitations of the available data: The NVD description does not enumerate specific function names, class names, file paths, URL endpoints, or API parameters. Accordingly, no such specifics are asserted here. The precise nesting threshold required to crash a given process depends on the Node.js stack size (--stack-size), the V8 version, and the amount of stack already consumed at the point of the call — none of which are specified in the provided data.
Exploitation Scenarios
No public PoC or exploit code is available, and no Nuclei template exists. The attack chain below is described at the vulnerability-class level, consistent strictly with the NVD description. No function names, endpoints, or parameters are invented.
Reconnaissance / target identification. The attacker identifies a Node.js service that accepts string input which is subsequently passed to the braces library for pattern expansion. Because braces is frequently a transitive dependency, the attacker reasons about indirect exposure: any endpoint accepting a pattern-like or path-like string may reach a recursive walker. Reconnaissance is passive — fingerprinting Node.js services (e.g., response headers, default error pages) and mapping input fields capable of carrying brace-delimited strings.
Triggering the flaw class. The attacker submits a crafted input string consisting of deeply nested brace patterns. The key property, per the description, is that the nesting is constructed to remain under the character limit enforced by the consuming application, exploiting the fact that deep AST structure can be encoded compactly within a short string. When the application hands this string to braces, the recursive AST walker descends without a depth guard.
Payload / execution method (class-level). This is a logic/parsing-input attack, not a memory-safety exploit. The "payload" is a syntactically valid but pathologically nested brace pattern supplied through whatever input channel reaches the parser (request parameter, header, body field, CLI argument, or repository file consumed by a build job). No shellcode, gadget chain, or memory corruption primitive is involved — the objective is maximal recursion depth per character.
Post-exploitation impact. Stack exhaustion raises an uncaught
RangeErrorand terminates the Node.js process. In a single-process deployment this yields complete service unavailability for that worker; in a clustered or containerized deployment it produces repeated worker restarts. The attacker can repeat the request to maintain a denial-of-service condition. There is no evidence in the provided data of confidentiality or integrity loss, lateral movement, or code execution — the impact is strictly availability.
Impact Assessment
- CVSS: 7.5 (High) —
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. - Attack Vector (AV:N): Remotely triggerable over the network where the parsing path is exposed to network input.
- Attack Complexity (AC:L): No special conditions; the description implies a low-complexity trigger given the character-limit bypass.
- Privileges Required (PR:N) / User Interaction (UI:N): Fully unauthenticated and requires no victim interaction.
- Scope (S:U): Impact confined to the vulnerable component.
- Confidentiality (C:N) / Integrity (I:N): No data exposure or modification.
- Availability (A:H): Total loss of availability of the affected Node.js process.
Business impact: Service outages for any internet-facing Node.js application whose request handling reaches a vulnerable braces recursive walker. Because braces is commonly a transitive dependency, the blast radius can extend into CI/CD pipelines and build tooling — a crash in a build worker can stall deployments. For multi-tenant or single-worker deployments, a single crafted request can cause a full outage. EPSS has not yet been scored by FIRST.org, and CVE-2026-93687 is not listed in CISA KEV, indicating no confirmed exploitation in the wild at the time of writing.
Detection Guidance
Detection focuses on (a) correlated process crashes / uncaught RangeError events in Node.js logs and (b) pathological brace-nesting patterns in inbound requests. Because no public PoC exists, the signatures below target the vulnerability class rather than a known payload.
Sigma Rule
title: Potential braces Stack Overflow DoS via Deeply Nested Pattern Input
id: 7c9f1a2e-93c4-4b2e-8a51-braces002
status: experimental
description: Detects repeated Node.js process termination with uncaught RangeError consistent with CVE-2026-93687 (braces recursive AST walker stack overflow).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-93687
author: valtersit.com
date: 2026/01/01
logsource:
product: linux
service: application
detection:
selection_range:
message|contains:
- 'RangeError'
- 'Maximum call stack size exceeded'
selection_braces:
message|contains:
- 'braces'
- 'expand'
selection_crash:
message|contains:
- 'node'
- 'uncaughtException'
condition: selection_range and (selection_braces or selection_crash)
falsepositives:
- Legitimate applications with deep recursion unrelated to braces
- Developer error during normal operation
level: high
YARA Rule
rule CVE_2026_93687_braces_DeepNesting_DoS
{
meta:
description = "Detects deeply nested brace pattern strings associated with CVE-2026-93687 (braces <= 3.0.3 stack overflow)"
author = "valtersit.com"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-93687"
date = "2026-01-01"
severity = "high"
strings:
$deep_nest_1 = /\{[^{}]{0,4}\{[^{}]{0,4}\{[^{}]{0,4}\{[^{}]{0,4}\{[^{}]{0,4}\{/
$deep_nest_2 = /\{[^{}]{1,8}\{[^{}]{1,8}\{[^{}]{1,8}\{[^{}]{1,8}\{[^{}]{1,8}\{[^{}]{1,8}\{/
$range_error = "Maximum call stack size exceeded"
$braces_ref = "braces"
condition:
(uint16(0) == 0x7B7B or uint16(0) == 0x5B7B) or
($range_error and $braces_ref) or
(any of ($deep_nest_*))
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-93687 braces Stack Overflow DoS Attempt (Deeply Nested Brace Pattern)"; flow:to_server,established; http.uri; pcre:"/(?:%7B|\{)(?:[^{}%]{0,10}(?:%7B|\{)){12,}/i"; metadata:service http, cve CVE-2026-93687; classtype:attempted-dos; reference:cve,CVE-2026-93687; sid:9000001; rev:1;)
Elastic Detection
sequence by host.name
[process where process.name == "node" and event.action == "end" and process.exit_code != 0]
[process where process.name == "node" and event.action == "start"]
Splunk SPL Query
index=app_logs (source="*node*" OR source="*express*")
| search ("RangeError" OR "Maximum call stack size exceeded" OR "braces")
| eval sev=case(
match(_raw,"Maximum call stack size exceeded"),"CRITICAL",
match(_raw,"RangeError"),"HIGH",
true(),"MEDIUM")
| stats count min(_time) as first_seen max(_time) as last_seen values(sev) as severity by host, source
| where count >= 3
| sort - count
Wazuh OSSEC Rule
<group name="nodejs,web,braces_dos,">
<rule id="110901" level="0">
<decoded_as>json</decoded_as>
<match>node</match>
<description>Node.js log event (base).</description>
</rule>
<rule id="110902" level="12" frequency="3" timeframe="120">
<if_matched_sid>110901</if_matched_sid>
<match>Maximum call stack size exceeded</match>
<description>CVE-2026-93687: Possible braces stack overflow DoS (uncaught RangeError) on $(hostname).</description>
<mitre>
<id>T1190</id>
</mitre>
<group>cve_2026_93687,denial_of_service,</group>
</rule>
<rule id="110903" level="12" frequency="3" timeframe="120">
<if_matched_sid>110901</if_matched_sid>
<match>RangeError</match>
<regex>braces|expandPattern|AST</regex>
<description>CVE-2026-93687: braces recursive walker failure detected on $(hostname).</description>
<group>cve_2026_93687,denial_of_service,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED). No patch evidence exists from any tracked source; no vendor fix, workaround, or affected-version advisory is currently available. The guidance below reflects conservative, defense-in-depth measures for an unpatched uncontrolled-recursion (CWE-674) flaw.
Immediate mitigations
- Input length and depth limiting: Enforce strict maximum lengths on any attacker-controllable string that may reach braces. Because the flaw bypasses naive character limits, combine length limits with explicit nesting-depth validation: reject inputs whose brace-nesting depth exceeds a safe threshold before parsing.
- Pre-validation at the edge: Add regex- or counter-based pre-checks in reverse proxies (e.g., Nginx, HAProxy) and API gateways to reject pathologically nested brace patterns early.
- Process isolation and supervision: Run Node.js workers under a supervisor (PM2, systemd, Kubernetes) with automatic restart and rate limiting so a single crash does not cause sustained outage. Enable Node.js clustering so worker termination does not take down the service.
- Tune stack and error handling: Install
process.on('uncaughtException')handlers to log and gracefully restart where feasible, and consider worker-based isolation of parsing activities in aworker_threadsorchild_processboundary so crashes are contained. - Rate-limit and WAF: Apply rate limiting and WAF rules targeting deeply nested brace patterns in request parameters.
Patch / upgrade steps
- No fixed version is documented. Monitor the braces project's repository, the NPM security advisory database, and the NVD entry for CVE-2026-93687 for a patched release.
- When an update becomes available, upgrade the direct dependency and force-resolve the transitive dependency tree (
npm ls braces,npm audit,overrides/resolutionsin package.json) to eliminate vulnerable copies. - Rebuild lockfiles and redeploy; verify with
npm auditthat no version at or below 3.0.3 remains. - If no patched release is forthcoming, evaluate replacing braces with a maintained alternative or wrapping its use with the depth guard described above.
Long-term hardening
- Add dependency-scoping policies to track transitive usage of parsing libraries.
- Integrate SAST/SCA tooling into CI/CD to flag uncontrolled recursion (CWE-674) patterns.
- Adopt resource-bounded parsing libraries that enforce recursion limits by design.
- Include DoS crash scenarios in resilience testing, validating supervisor restart behavior and rate limiting.
References
- NVD — CVE-2026-93687: https://nvd.nist.gov/vuln/detail/CVE-2026-93687
- MITRE CWE-674 — Uncontrolled Recursion: https://cwe.mitre.org/data/definitions/674.html
- NPM Security Advisories (braces package): https://www.npmjs.com/advisories (monitor for a CVE-2026-93687 entry)
- FIRST EPSS: https://www.first.org/epss/ (currently no score for this CVE)
- CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog (CVE-2026-93687 not listed — no KEV evidence)
Threat actor / exploitation status: No public PoC, exploit code, or Nuclei template is available. CVE-2026-93687 is not in CISA KEV, and no threat actor campaign or in-the-wild exploitation evidence is present in the provided data. EPSS has not been scored by FIRST.org; no EPSS value is fabricated here.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.