Repository navigation
fix: bound parser nesting and recursive AST traversal - #78
thaibaole89 wants to merge 1 commit into
Conversation
braces 3.0.3 (CVE-2026-93687) is reached only at lint time through eslint-plugin-next -> fast-glob -> micromatch, on glob patterns this repo writes itself, and upstream has three fix PRs open (micromatch/braces#78, #79, #82). Leave the finding visible so it clears on its own when the patched release reaches the lockfile.
ulises-jeremias
left a comment
There was a problem hiding this comment.
I independently tested the current head 97308a0 with the upstream test suite on Node 22.22.0: npm test passes all 908 tests. This includes the new nesting/depth cases. GitHub currently reports no CI checks for this PR, and no npm release is available yet, so consumers cannot adopt it as a supported dependency update until it is merged and published.
|
We tested an additional local guard against the published 3.0.3 package while working on the existing stack exhaustion advisory. This feedback is intended to complement the current PR rather than duplicate it. A parser-only nesting cap does not cover the public AST entry points: const braces = require('braces');
let ast = { type: 'text', value: 'x' };
for (let i = 0; i < 20000; i++) ast = { type: 'root', nodes: [ast] };
braces.compile(ast); // RangeError with the unpatched package on Node 24.19.0Our local patch checks The guard runs before the existing recursive walkers and throws a controlled Validation: 37 tests passed, 0 failed on Node 24.19.0, covering the existing compile/expand/parse fixtures and three new regression tests for deep strings, deep/cyclic/shared ASTs, and ordinary escape/range behaviour. The fixture harness uses Node's test runner with the existing Mocha-style globals; this is not a claim that the complete Mocha suite or the Node 8 compatibility matrix was run. On this Node 24 runtime, the balanced 4000-level string case did not reproduce a stack overflow at the default stack size. The direct AST case above did, so we kept that distinction in the evidence. |
Turns out this CVE seems illegitimate (cf github/advisory-database#10132), and several implementation PRs exist. Existing alternatives: - micromatch#78: Bound parser nesting and recursive AST traversal. micromatch#78 - micromatch#79: Treat nesting beyond the depth limit as literal text. micromatch#79 - micromatch#82: Preflight AST walkers and derive expansion queues from traversal. micromatch#82 - micromatch#87: Bound nested AST traversal and detect cyclic parent chains. micromatch#87 - micromatch#88: Validate parser and supplied AST depth before recursive processing. micromatch#88
Deeply nested patterns below the existing character limit can overflow the recursive AST walkers. This change rejects excessive nesting with a controlled SyntaxError before the engine exhausts its stack.
nodestrees, which bypass parsing.Addresses #70 / GHSA-vfj7-8cjw-p6xm. Related to #77, which proposes an opt-in maxDepth option; this proposal provides a mandatory default bound for existing callers that pass no option. Maintainer input on the threshold/API is welcome.
Validation:
npm teston Node 24.14.1, 908 pass, including 14 new cases.This bounds parser and AST
nodesrecursion depth; it does not cap expansion cardinality or claim safety for every malformed AST field/getter/parent structure or resource-exhaustion input. For example, a malformed array-valued text node can still reach unguarded flattening; the parser does not emit that shape. No general CPU/memory or regex-safety claim is made.AI assistance: OpenAI Codex was used to prepare the patch, tests and independent review.