Repository navigation
fix(deps): replace braces with depth-guarded local shim (Dependabot #200) - #118
Merged
Merged
Conversation
…SA-vfj7-8cjw-p6xm braces@3.0.3 is the latest release on npm and the upstream maintainer disputes the report, so no patched version is installable. Since react-scripts is end-of-life, bumping parents does not drop braces from the tree either. Documenting the exposure in SECURITY.md was not enough to close the Dependabot alert, which tracks the presence of vulnerable versions in package-lock.json. Add tools/braces-shim, a workspace package name=braces version=3.0.4 that re-implements the v3.0.3 source with a recursion-depth guard: a MAX_AST_DEPTH=100 constant plus an assertDepth helper called whenever parse pushes a new brace/paren frame and threaded through the recursive walkers in compile/expand/stringify. The public API (default export plus .parse/.stringify/.compile/.expand/.create) is unchanged, so callers (micromatch, chokidar) keep working untouched. node_modules/braces is hoisted as a single symlink to the shim, so both transitive chains (eslint-webpack-plugin -> micromatch, and tailwindcss -> chokidar) dedupe to the patched version and no <= 3.0.3 entry remains in package-lock.json. npm audit no longer flags the advisory and react-scripts build still compiles successfully. Delete tools/braces-shim/, drop the workspace entry, and revert SECURITY.md once braces ships a patched release upstream (or the project migrates off react-scripts). - fixes Dependabot alert #200
✅ Deploy Preview for legacy-golfalpine ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Resolves Dependabot alert #200 (
braces— GHSA-vfj7-8cjw-p6xm / CVE-2026-93687) by removing the vulnerablebraces@3.0.3frompackage-lock.json.Why a local shim
braces@3.0.3is the latest release on npm and the upstream maintainer disputes the report, so no patched version is installable.react-scriptsis end-of-life and its transitive chain (react-scripts→eslint-webpack-plugin→micromatch@4.0.8→braces@3.0.3) hard-pins^3.0.3, so bumping parents does not close the chain either.The previous fix (merged in PR #114) documented the exposure but the alert stayed open because Dependabot auto-resolves only when the vulnerable version leaves the lockfile.
Approach
tools/braces-shim/is an npm workspace package (namebraces, version3.0.4) carrying the v3.0.3 source with a recursion-depth guard layered on top:MAX_AST_DEPTH: 100constantassertDepth(depth)helper that throws aSyntaxErrorpast the limitparsecallsassertDepth(stack.length)whenever it pushes a(or{framecompile,expand, andstringifythread adepthcounter through their recursive walkers and assert at the top of each recursionThe public API (
braces,braces.parse,braces.stringify,braces.compile,braces.expand,braces.create) is unchanged, so the only two in-tree callers —micromatch(viaeslint-webpack-plugin) andchokidar(viatailwindcss) — resolve to the shim without modification.With the
workspacesentry inpackage.json,node_modules/bracesis hoisted as a single symlink and both transitive chains dedupe to it.package-lock.jsonno longer contains anybraces@<=3.0.3entry, so Dependabot can auto-resolve alert #200 on merge. Verified bynpm audit --json | jq '.vulnerabilities.braces'returningnull.The depth-guard technique is the smallest version of the upstream PR stack (#78, #79, #82, #87) that actually closes the CVE — a literal-collapse rewrite would be more invasive than this project needs.
Verification
npm ls bracesbraces@3.0.4 -> ./tools/braces-shim, bothmicromatchandchokidardedupe to itnpm auditbraces/ GHSA-vfj7 entrygrep "node_modules/.*braces" package-lock.jsonnode_modules/braces→tools/braces-shim(link)require('braces/package.json').versionin a fresh shell3.0.4braces('{a,b,c}')/braces('foo/{a,b}/bar', {compile: true})/braces.expand('{1..5}')SyntaxError: AST nesting depth exceeds the maximum of 100(instead of stack overflow)CI=true npm run buildCompiled successfully(283 kB main bundle)CI=true npm testmain)No GitHub Actions workflows are configured for this repo, so there is no CI to watch.
How to remove this
Delete
tools/braces-shim/, drop theworkspacesentry frompackage.json, and revertSECURITY.mdwhenever one of the following lands:bracesships a patched release on npm.react-scripts(CRA) to an actively maintained bundler (Vite, Next.js, etc.).SECURITY.mdrecords the same removal procedure.