brace-expansion
Ecosystem: npm
Downloads: 2.74 Bln
- 0CriticalAffects 0 versions
- 6HighAffects 20 versions
- 0MediumAffects 0 versions
- 3ModerateAffects 9 versions
- 1LowAffects 4 versions
- Critical0 (0.0%)
- High6 (60.0%)
- Medium0 (0.0%)
- Moderate3 (30.0%)
- Low1 (10.0%)
Monthly breakdown
- Critical
- High
- Medium
- Moderate
- Low
- 3 vulnerabilities
- Critical: 0
- High: 2
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 2 vulnerabilities
- Critical: 0
- High: 2
- Medium: 0
- Moderate: 0
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 0
- Low: 1
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
Vulnerabilities (10)
Known vulnerabilities affecting brace-expansion, based on data from OSV.
| ID | Severity | Summary | Affected versions | Published | Source |
|---|---|---|---|---|---|
| GHSA-6j4f-fj2g-mc7p | High | brace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion### Summary `parseCommaParts()` can exhaust the native stack and crash the process. There are two distinct ways to trigger it, both reachable from a single untrusted pattern string. This is the parsing-side counterpart to CVE-2026-14257 / GHSA-mh99-v99m-4gvg. That fix made `expand_()` iterative and documented a constant-stack-depth guarantee, but `parseCommaParts()` was left recursive, so the guarantee only held for one of the two parsing paths. ### Vector 1 - unbounded recursion on `post` `parseCommaParts()` recursed on the remainder of the string once per brace group: ```js const postPa |
| GitHub (opens in a new tab) | |
| GHSA-q2hr-2g5m-vwhr | Moderate | brace-expansion: Quadratic-time expansion of the `{a},b}` rewrite causes CPU denial of service### Summary Expanding `{a},b}`-shaped input takes time quadratic in the number of literal `}` characters, blocking the event loop. Bash preserves a quirk where a brace group followed by a comma set still expands (`{a},b}`). The parser implements this by rewriting the string and restarting the scan. Each pass absorbs exactly one `}` and re-scans from the beginning, so `n` trailing braces cost `n` full passes. ### Reproduction ```js const build = n => '{a}' + '}'.repeat(n) + ',z}' for (const n of [8000, 16000, 32000, 64000, 128000]) { const t = Date.now() expand(build(n)) console.log( |
| GitHub (opens in a new tab) | |
| GHSA-qhr7-859c-m2p7 | High | brace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion### Summary `expand_()` recurses once per level of brace *nesting*. Deeply nested input exhausts the native stack and crashes the process. This is distinct from CVE-2026-14257 / GHSA-mh99-v99m-4gvg, which made the *tail* iterative (recursion on `m.post`, driven by how many groups are chained). Nesting depth drives a different recursion that the tail fix never touched, so the documented constant-stack-depth guarantee only ever covered chained input, not nested input. It is also distinct from GHSA-6j4f-fj2g-mc7p, which fixed recursion in `parseCommaParts()`. Both payloads below still crash wi |
| GitHub (opens in a new tab) | |
| GHSA-rgw5-rvv9-x895 | High | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation### Summary The `maxLength` mitigation added in `5.0.8` for GHSA-mh99-v99m-4gvg / CVE-2026-14257 is incomplete. It bounds the accumulator where results are *combined*, but not the intermediate arrays that feed it. A ~25 KB input still crashes the Node process with an **uncatchable** out-of-memory error, so `try/catch` around `expand()` does not help. A second, related path in the same function lets a ~400 KB input block the event loop for over two minutes without ever exceeding the memory bound. ### Details `maxLength` was enforced in `combine()`, the single place output grows. Two arrays |
| GitHub (opens in a new tab) | |
| GHSA-mh99-v99m-4gvg | High | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash### Summary `expand()` bounds the *number* of results it produces (the `max` option, `100_000` by default) but not their *length*. By chaining many brace groups, an attacker keeps the result count under `max` while making every result grow with the number of groups. Building `max` long results — plus the intermediate arrays combined at each brace group — exhausts memory and crashes the Node process with an **uncatchable** out-of-memory error. `try/catch` around `expand()` does not help: the fatal error terminates the process. A ~7.5 KB input (`'{a,b}'.repeat(1500)`) is enough to crash a defa |
| GitHub (opens in a new tab) | |
| GHSA-3jxr-9vmj-r5cp | High | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups### 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: ```js const post = m.post.length ? expand_(m.post, max, false) : |
| GitHub (opens in a new tab) | |
| GHSA-jxxr-4gwj-5jf2 | Moderate | brace-expansion: Large numeric range defeats documented `max` DoS protectionThe `max` option was being applied too late: When expanding a single large numeric range like `{1..10000000}`, the sequence generation loop generates all 10 million intermediate elements before the `max` limit is applied With `max=10`, the output is correctly limited to 10 items, but the process still allocates `~505 MB` and spends `~800ms` building the full intermediate array. ### Workaround Ensure the string to be expanded doesn't contain more values than the desired `max` item count. |
| GitHub (opens in a new tab) | |
| GHSA-f886-m6hf-6m8v | Moderate | brace-expansion: Zero-step sequence causes process hang and memory exhaustion### Impact A brace pattern with a zero step value (e.g., `{1..2..0}`) causes the sequence generation loop to run indefinitely, making the process hang for seconds and allocate heaps of memory. The loop in question: https://github.com/juliangruber/brace-expansion/blob/daa71bcb4a30a2df9bcb7f7b8daaf2ab30e5794a/src/index.ts#L184 `test()` is one of https://github.com/juliangruber/brace-expansion/blob/daa71bcb4a30a2df9bcb7f7b8daaf2ab30e5794a/src/index.ts#L107-L113 The increment is computed as `Math.abs(0) = 0`, so the loop variable never advances. On a test machine, the process hangs for about |
| GitHub (opens in a new tab) | |
| GHSA-v6h2-p8h4-qcjw | Low | brace-expansion Regular Expression Denial of Service vulnerabilityA vulnerability was found in juliangruber brace-expansion up to 1.1.11/2.0.1/3.0.0/4.0.0. It has been rated as problematic. Affected by this issue is the function expand of the file index.js. The manipulation leads to inefficient regular expression complexity. The attack may be launched remotely. The complexity of an attack is rather high. The exploitation is known to be difficult. The exploit has been disclosed to the public and may be used. Upgrading to version 1.1.12, 2.0.2, 3.0.1 and 4.0.1 is able to address this issue. The name of the patch is `a5b98a4f30d7813266b221435e1eaaf25a1b0ac5`. I |
| GitHub (opens in a new tab) | |
| GHSA-832h-xg76-4gv6 | High | ReDoS in brace-expansionAffected versions of `brace-expansion` are vulnerable to a regular expression denial of service condition. ## Proof of Concept ``` var expand = require('brace-expansion'); expand('{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n}'); ``` ## Recommendation Update to version 1.1.7 or later. |
| GitHub (opens in a new tab) |
- GHSA-6j4f-fj2g-mc7pHighbrace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion
>= 4.0.0, < 5.0.10>= 3.0.0, < 3.0.7- +2 more
Affected versions:>= 4.0.0, < 5.0.10>= 3.0.0, < 3.0.7>= 2.0.0, < 2.1.5< 1.1.19
### Summary `parseCommaParts()` can exhaust the native stack and crash the process. There are two distinct ways to trigger it, both reachable from a single untrusted pattern string. This is the parsing-side counterpart to CVE-2026-14257 / GHSA-mh99-v99m-4gvg. That fix made `expand_()` iterative and documented a constant-stack-depth guarantee, but `parseCommaParts()` was left recursive, so the guarantee only held for one of the two parsing paths. ### Vector 1 - unbounded recursion on `post` `parseCommaParts()` recursed on the remainder of the string once per brace group: ```js const postPa
CVE: CVE-2026-102276
- GHSA-q2hr-2g5m-vwhrModeratebrace-expansion: Quadratic-time expansion of the `{a},b}` rewrite causes CPU denial of service
>= 4.0.0, < 5.0.12>= 3.0.0, < 3.0.9- +2 more
Affected versions:>= 4.0.0, < 5.0.12>= 3.0.0, < 3.0.9>= 2.0.0, < 2.1.7< 1.1.21
### Summary Expanding `{a},b}`-shaped input takes time quadratic in the number of literal `}` characters, blocking the event loop. Bash preserves a quirk where a brace group followed by a comma set still expands (`{a},b}`). The parser implements this by rewriting the string and restarting the scan. Each pass absorbs exactly one `}` and re-scans from the beginning, so `n` trailing braces cost `n` full passes. ### Reproduction ```js const build = n => '{a}' + '}'.repeat(n) + ',z}' for (const n of [8000, 16000, 32000, 64000, 128000]) { const t = Date.now() expand(build(n)) console.log(
CVE: CVE-2026-102277
- GHSA-qhr7-859c-m2p7Highbrace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion
>= 4.0.0, < 5.0.11>= 3.0.0, < 3.0.8- +2 more
Affected versions:>= 4.0.0, < 5.0.11>= 3.0.0, < 3.0.8>= 2.0.0, < 2.1.6< 1.1.20
### Summary `expand_()` recurses once per level of brace *nesting*. Deeply nested input exhausts the native stack and crashes the process. This is distinct from CVE-2026-14257 / GHSA-mh99-v99m-4gvg, which made the *tail* iterative (recursion on `m.post`, driven by how many groups are chained). Nesting depth drives a different recursion that the tail fix never touched, so the documented constant-stack-depth guarantee only ever covered chained input, not nested input. It is also distinct from GHSA-6j4f-fj2g-mc7p, which fixed recursion in `parseCommaParts()`. Both payloads below still crash wi
CVE: CVE-2026-102278
- GHSA-rgw5-rvv9-x895Highbrace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation
< 1.1.18>= 2.0.0, < 2.1.4- +2 more
Affected versions:< 1.1.18>= 2.0.0, < 2.1.4>= 3.0.0, < 3.0.6>= 4.0.0, < 5.0.9
### Summary The `maxLength` mitigation added in `5.0.8` for GHSA-mh99-v99m-4gvg / CVE-2026-14257 is incomplete. It bounds the accumulator where results are *combined*, but not the intermediate arrays that feed it. A ~25 KB input still crashes the Node process with an **uncatchable** out-of-memory error, so `try/catch` around `expand()` does not help. A second, related path in the same function lets a ~400 KB input block the event loop for over two minutes without ever exceeding the memory bound. ### Details `maxLength` was enforced in `combine()`, the single place output grows. Two arrays
CVE: CVE-2026-69152
- GHSA-mh99-v99m-4gvgHighbrace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash
>= 4.0.0, < 5.0.8>= 3.0.0, < 3.0.3- +2 more
Affected versions:>= 4.0.0, < 5.0.8>= 3.0.0, < 3.0.3>= 2.0.0, < 2.1.3< 1.1.17
### Summary `expand()` bounds the *number* of results it produces (the `max` option, `100_000` by default) but not their *length*. By chaining many brace groups, an attacker keeps the result count under `max` while making every result grow with the number of groups. Building `max` long results — plus the intermediate arrays combined at each brace group — exhausts memory and crashes the Node process with an **uncatchable** out-of-memory error. `try/catch` around `expand()` does not help: the fatal error terminates the process. A ~7.5 KB input (`'{a,b}'.repeat(1500)`) is enough to crash a defa
CVE: CVE-2026-14257
- GHSA-3jxr-9vmj-r5cpHighbrace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups
>= 3.0.0, < 5.0.7< 1.1.16- +1 more
Affected versions:>= 3.0.0, < 5.0.7< 1.1.16>= 2.0.0, < 2.1.2
### 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: ```js const post = m.post.length ? expand_(m.post, max, false) :
CVE: CVE-2026-13149
- GHSA-jxxr-4gwj-5jf2Moderatebrace-expansion: Large numeric range defeats documented `max` DoS protection
>= 5.0.0, < 5.0.6
The `max` option was being applied too late: When expanding a single large numeric range like `{1..10000000}`, the sequence generation loop generates all 10 million intermediate elements before the `max` limit is applied With `max=10`, the output is correctly limited to 10 items, but the process still allocates `~505 MB` and spends `~800ms` building the full intermediate array. ### Workaround Ensure the string to be expanded doesn't contain more values than the desired `max` item count.
CVE: CVE-2026-45149
- GHSA-f886-m6hf-6m8vModeratebrace-expansion: Zero-step sequence causes process hang and memory exhaustion
>= 4.0.0, < 5.0.5>= 3.0.0, < 3.0.2- +2 more
Affected versions:>= 4.0.0, < 5.0.5>= 3.0.0, < 3.0.2>= 2.0.0, < 2.0.3< 1.1.13
### Impact A brace pattern with a zero step value (e.g., `{1..2..0}`) causes the sequence generation loop to run indefinitely, making the process hang for seconds and allocate heaps of memory. The loop in question: https://github.com/juliangruber/brace-expansion/blob/daa71bcb4a30a2df9bcb7f7b8daaf2ab30e5794a/src/index.ts#L184 `test()` is one of https://github.com/juliangruber/brace-expansion/blob/daa71bcb4a30a2df9bcb7f7b8daaf2ab30e5794a/src/index.ts#L107-L113 The increment is computed as `Math.abs(0) = 0`, so the loop variable never advances. On a test machine, the process hangs for about
CVE: CVE-2026-33750
- GHSA-v6h2-p8h4-qcjwLowbrace-expansion Regular Expression Denial of Service vulnerability
>= 2.0.0, < 2.0.2>= 1.0.0, < 1.1.12- +2 more
Affected versions:>= 2.0.0, < 2.0.2>= 1.0.0, < 1.1.12>= 3.0.0, < 3.0.1>= 4.0.0, < 4.0.1
A vulnerability was found in juliangruber brace-expansion up to 1.1.11/2.0.1/3.0.0/4.0.0. It has been rated as problematic. Affected by this issue is the function expand of the file index.js. The manipulation leads to inefficient regular expression complexity. The attack may be launched remotely. The complexity of an attack is rather high. The exploitation is known to be difficult. The exploit has been disclosed to the public and may be used. Upgrading to version 1.1.12, 2.0.2, 3.0.1 and 4.0.1 is able to address this issue. The name of the patch is `a5b98a4f30d7813266b221435e1eaaf25a1b0ac5`. I
CVE: CVE-2025-5889
Affected versions of `brace-expansion` are vulnerable to a regular expression denial of service condition. ## Proof of Concept ``` var expand = require('brace-expansion'); expand('{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n}'); ``` ## Recommendation Update to version 1.1.7 or later.
CVE: CVE-2017-18077