fix: upgrade brace-expansion transitive dep to patch CVE-2026-13149 (GHSA-3jxr-9vmj-r5cp) - #2694
Draft
jainakanksha-msft with Copilot wants to merge 2 commits into
Draft
fix: upgrade brace-expansion transitive dep to patch CVE-2026-13149 (GHSA-3jxr-9vmj-r5cp)#2694jainakanksha-msft with Copilot wants to merge 2 commits into
jainakanksha-msft with Copilot wants to merge 2 commits into
Conversation
Copilot
AI
changed the title
[WIP] Fix brace-expansion DoS vulnerability
fix: upgrade brace-expansion transitive dep to patch CVE-2026-13149 (GHSA-3jxr-9vmj-r5cp)
Aug 3, 2026
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.
brace-expansion@5.0.6has an O(2ⁿ) ReDoS via consecutive non-expanding{}groups — a ~90-byte input can block the Node.js event loop for minutes.Changes
package.json: Added a scoped npm override to forcebrace-expansion ≥ 5.0.7withinglob's dependency subtree (the only path pulling in the vulnerable version):package-lock.json: Regenerated —node_modules/glob/node_modules/brace-expansionnow resolves to5.0.9(was5.0.6).Reachability
Not reachable in production (high confidence). The vulnerable package enters via
glob@13.0.6 → minimatch@10.2.5 → brace-expansion@5.0.6, whereglob@13is a dev-only dependency. No production source code callsbrace-expansion.expand()directly or transitively. This update removes the vulnerability from the dev toolchain and satisfies vulnerability scanners.Original prompt
This section details the Dependabot vulnerability alert you should resolve
<alert_title>brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups</alert_title>
<alert_description>### Summary
brace-expansion's expand() exhibits exponential-time - O(2ⁿ) - behavior in the number of consecutive non-expanding {} groups. A short, all-ASCII input (~90 bytes/30 groups) blocks the calling thread for minutes; a slightly longer input hangs it effectively indefinitely. Because the dominant consumers run on Node's single-threaded event loop, one small input can fully stall a worker/process.
In
expand_,postis computed unconditionally at the top of the function, before the early-return branches that don't use it:For input like a{},{},…, the first {} is non-expanding, so control reaches the {a},b} rewrite branch - but
expand_has already recursed into post over the entire remaining tail, only to throw the result away.Each level therefore spawns two recursive expansions over essentially the same remaining work:
T(n) = 2·T(n−1) ⇒ O(2ⁿ).The max option does not mitigate this: max only bounds the output-building loops; neither the post recursion nor the rewrite recursion consults it.
Measured on 5.0.6:
Proof of concept
Impact
Any application that passes attacker-influenced strings to brace-expansion.expand() - directly or transitively via minimatch/glob brace patterns - can be driven into a multi-minute-to-indefinite CPU hang by a tiny request, denying service on that thread/process.
Remediation
Upgrade to a patched release. The fix:
Verified: the PoC drops from ~2 min to 0.55 ms, 5,000 groups complete in ~344 ms, and output is identical to 5.0.6 across a behavioral-equivalence suite (sequences, padding, $-prefix, a{},b}c, {},a}b, x{{a,b}}y, etc.). Post-fix complexity is ~O(n²) on this input class - acceptable for the security fix; a linear rewrite can be a non-urgent follow-up.
If immediate upgrade isn't possible, avoid passing untrusted input to expand() / glob brace patterns, or run such expansion under a timeout/worker.</alert_description>
high
https://github.com/juliangruber/brace-expansion/security/advisories/GHSA-3jxr-9vmj-r5cp https://nvd.nist.gov/vuln/detail/CVE-2026-13149 https://github.com/juliangruber/brace-expansion/pull/122 https://github.com/juliangruber/brace-expansion/pull/123 https://github.com/juliangruber/brace-expansion/commit/835d6be91201122d9adffb0c0c8c094189ace265 https://github.com/juliangruber/brace-expansion/commit/c7e33ec13ac1a684c116720843ce24e208611754 https://github.com/juliangruber/brace-expansion/commit/d74e63030c012e3b7ae81657b8d665619cd51b95 https://github.com/juliangruber/brace-expansion/releases/tag/v1.1.16 https://github.com/juliangruber/brace-expansion/releases/tag/v2.1.2 https://github.com/juliangruber/brace-expansion/releases/tag/v5.0.7 https://www.npmjs.com/package/brace-expansion https://github.com/advisories/GHSA-3jxr-9vmj-r5cpGHSA-3jxr-9vmj-r5cp, CVE-2026-13149
brace-expansion
npm
<vulnerable_versions>5.0.6</vulnerable_versions>
<patched_version>5.0.7</patched_version>
<manifest_path>package-lock.json</manifest_path>
<agent_instructions>@copilot please go through the issues mentioned here, identify all issues, and assess whether they can be fixed.
Recommend the necessary changes.
If it is not a breaking change, let's log the issue.
Please verify all test cases and validate the runs.
</agent_instructions>
<task_instructions>Resolve this alert by updating the affected package to a non-vulnerable version. Prefer the lowest non-vulnerable version (see the patched_version field above) over the latest to minimize breaking changes. Include a Reachability ...