chore(deps): update dependency brace-expansion@>=2.0.0 <2.1.2 to v5 [security] - #2139
Open
renovate[bot] wants to merge 1 commit into
Open
chore(deps): update dependency brace-expansion@>=2.0.0 <2.1.2 to v5 [security]#2139renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
|
renovate
Bot
force-pushed
the
renovate/npm-brace-expansion-=2.0.0-2.1.2-vulnerability
branch
2 times, most recently
from
July 27, 2026 20:32
5b2ae31 to
b1f0c85
Compare
renovate
Bot
force-pushed
the
renovate/npm-brace-expansion-=2.0.0-2.1.2-vulnerability
branch
from
July 27, 2026 20:36
b1f0c85 to
a47d288
Compare
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.
This PR contains the following updates:
^2.1.2→^5.0.8](https://renovatebot.com/diffs/npm/brace-expansion@>=2.0.0 <2.1.2/2.1.2/5.0.8)brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash
CVE-2026-14257 / GHSA-mh99-v99m-4gvg
More information
Details
Summary
expand()bounds the number of results it produces (themaxoption,100_000by default) but not their length. By chaining many brace groups,an attacker keeps the result count under
maxwhile making every result growwith the number of groups. Building
maxlong results — plus the intermediatearrays combined at each brace group — exhausts memory and crashes the Node
process with an uncatchable out-of-memory error.
try/catcharoundexpand()does not help: the fatal error terminates the process.A ~7.5 KB input (
'{a,b}'.repeat(1500)) is enough to crash a default Nodeprocess.
Details
For
Nchained brace groups such as'{a,b}'.repeat(N):2^N, immediately capped atmax(100_000), so themaxprotection appears to hold, butNcharacters long, so the total output size ismax × Ncharacters, which grows without bound inN.expand_combines each brace set with the fully-expanded tail:The loop guard
expansions.length < maxlimits how many strings are built, butnothing limits how long they get. Each recursion level materializes another
array of up to
maxstrings, one character longer than the level below, and —because V8 represents
pre + N[j] + post[k]as a cons-string (rope) thatreferences
post[k]— those intermediate strings stay reachable through thewhole chain. Memory therefore scales with
max × N.Measured on
5.0.7('{a,b}'.repeat(N), defaultmax):Proof of concept
Impact
Any application that passes attacker-influenced strings to
brace-expansion.expand()— directly, or transitively viaminimatch/globbrace patterns — can be crashed by a small request. Because the failure is a
fatal V8 out-of-memory error rather than a thrown exception, it cannot be caught
and it takes down the whole worker/process, denying service.
Remediation
Upgrade to a patched release. The fix bounds the total number of characters a
single
expand()call may accumulate (EXPANSION_MAX_LENGTH, default4_000_000, configurable via a newmaxLengthoption), applied inside theoutput-building loops so intermediate arrays are bounded too. Once the limit is
reached, output is truncated — consistent with how
maxalready truncates —instead of growing without bound. The limit sits well above any realistic
expansion (100,000 results hitting
maxmeasure ~1M characters), so legitimateinput is unaffected.
After the fix,
'{a,b}'.repeat(1500)returns a bounded, truncated result in~0.7 s using ~340 MB and never crashes, including under a constrained 512 MB
heap.
The fix bounds memory but the algorithm still rebuilds intermediate arrays at
each level (roughly
O(N × maxLength)work on this input class). A streamingrewrite that produces output in
O(total output size)can be a non-urgentfollow-up.
If immediate upgrade isn't possible, avoid passing untrusted input to
expand()/ glob brace patterns, or pass a small explicitmaxandmaxLength.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
juliangruber/brace-expansion (brace-expansion@>=2.0.0 <2.1.2)
v5.0.8Compare Source
v5.0.7Compare Source
v5.0.6Compare Source
v5.0.5Compare Source
v5.0.4Compare Source
v5.0.3Compare Source
v5.0.2Compare Source
v4.0.1Compare Source
5a5cc170b6a978v4.0.0Compare Source
278132bdd72a59tea.yaml70e4c1bAs a precaution to not risk breaking anything with
278132b, this is a new semver major releasev3.0.3Compare Source
v3.0.2Compare Source
v3.0.1Compare Source
3059c078229e6f15f9b3cv3.0.0Compare Source
c0360e868c0e379e781e93494c4ddd5a4cb6dad209teste3dd8aed23ede91eb3fa41e7c9cd252053761a94f1dc741cf8ee56265c8756a05978a7Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.