Skip to content

chore(deps): update dependency brace-expansion@<1.1.13 to v5 [security] - #154

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-brace-expansion-1.1.13-vulnerability
Open

chore(deps): update dependency brace-expansion@<1.1.13 to v5 [security]#154
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-brace-expansion-1.1.13-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
brace-expansion@<1.1.13>=1.1.13>=5.0.7ageconfidence

brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups

CVE-2026-13149 / GHSA-3jxr-9vmj-r5cp

More information

Details

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_, post is computed unconditionally at the top of the function, before the early-return branches that don't use it:

constpost=m.post.length ? expand_(m.post,max,false) : [''];// always recurses
...
if(!isSequence&&!isOptions){if(m.post.match(/,(?!,).*\}/)){str=m.pre+'{'+m.body+escClose+m.post;returnexpand_(str,max,true);// restart — `post` discarded}return[str];}

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:

groups (n)input bytestime
2060130 ms
24721.9 s
26787.8 s
30 (PoC)90~2 min
Proof of concept
const{ expand }=require('brace-expansion');// 30 non-expanding groups, ~90 bytes — blocks for minutes:expand('a{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}');
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:

  1. Defers computing post until after the early-return branches (and computes it locally in the $-suffix branch), so post is only expanded when a brace set actually expands and the value is used. This alone removes the exponential.
  2. Converts the {a},b} rewrite from recursion to an in-function loop, so a long run of rewrites cannot grow the call stack.

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.

Severity

  • CVSS Score: 7.7 / 10 (High)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P/S:N/AU:Y/R:U/V:D/RE:M/U:Amber

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

juliangruber/brace-expansion (brace-expansion@<1.1.13)

v5.0.7

Compare Source

v5.0.6

Compare Source

v5.0.5

Compare Source

v5.0.4

Compare Source

v5.0.3

Compare Source

v5.0.2

Compare Source

v4.0.1

Compare Source


v4.0.0

Compare Source

As a precaution to not risk breaking anything with 278132b, this is a new semver major release

v3.0.6

Compare Source

v3.0.5

Compare Source

v3.0.4

Compare Source

v3.0.3

Compare Source

v3.0.2

Compare Source

v3.0.1

Compare Source


v3.0.0

Compare Source

v2.1.4

Compare Source

v2.1.3

Compare Source

v2.1.2

Compare Source

v2.1.1

Compare Source


v2.1.0

Compare Source

v2.0.3

Compare Source

v2.0.2

Compare Source


v2.0.1

Compare Source

v2.0.0

v1.1.17

Compare Source

v1.1.16

Compare Source

v1.1.15

Compare Source


v1.1.14

Compare Source


Configuration

📅 Schedule: (in timezone Europe/Zurich)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 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.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@changeset-bot

changeset-botBot commented Jul 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: e67457a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@renovaterenovateBot changed the title chore(deps): update dependency brace-expansion@<1.1.13 to >=1.1.16 [security]chore(deps): update dependency brace-expansion@<1.1.13 to v5 [security]Jul 25, 2026
@renovate
renovateBotforce-pushed the renovate/npm-brace-expansion-1.1.13-vulnerability branch 2 times, most recently from 0defdce to 0863d11CompareJuly 30, 2026 19:35
@renovaterenovateBot changed the title chore(deps): update dependency brace-expansion@<1.1.13 to v5 [security]chore(deps): update dependency brace-expansion@<1.1.13 to >=1.1.18 [security]Jul 30, 2026
@renovate
renovateBotforce-pushed the renovate/npm-brace-expansion-1.1.13-vulnerability branch from 0863d11 to e67457aCompareJuly 30, 2026 23:47
@renovaterenovateBot changed the title chore(deps): update dependency brace-expansion@<1.1.13 to >=1.1.18 [security]chore(deps): update dependency brace-expansion@<1.1.13 to v5 [security]Jul 30, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants