brace-expansion: 制御されていないネストされた括弧グループに対する再帰によってDoS攻撃が発生し、スタックが枯渇する。
### 概要
`expand_()`関数は、括弧のネストのレベルごとに1回ずつ再帰的に処理を行います。深くネストされた入力により、ネイティブスタックが枯渇し、プロセスがクラッシュします。
これは、CVE-2026-14257 / GHSA-mh99-v99m-4gvgとは異なります。この脆弱性は、`m.post`に対する反復処理(連鎖されたグループの数によって駆動)を*末尾*で行うものでした。ネストの深さは、別の種類の再帰を駆動し、この再帰は修正によって影響を受けませんでした。そのため、ドキュメントに記載されている「一定のスタック深度」の保証は、連鎖された入力に対してのみ適用され、ネストされた入力には適用されませんでした。
また、GHSA-6j4f-fj2g-mc7pとは異なります。この脆弱性は、`parseCommaParts()`関数における再帰を修正しました。以下に示すペイロードは、この修正が適用されていても依然としてクラッシュします。
### 再帰が発生する箇所
**カンマ区切りの要素。** 括弧セットの各代替要素は、再帰的な呼び出しによって展開されます。したがって、すべての代替要素の中にセットをネストすると、ネストのレベルごとに1回ずつ再帰が発生します。
```js
expand('{a,'.repeat(4000) + 'z' + '}'.repeat(4000))
// RangeError: Maximum call stack size exceeded
```
深度3,907でクラッシュします。入力は約**15.6 KB**です。
**単一のセット。** 括弧セットの本体が単一の要素に解析される場合、再帰的な呼び出しによって展開され、その後、再びラップされます(`x{{a,b}}y` -> `x{a}y x{b}y`)。これにより、ネストのレベルごとに1回ずつ再帰が発生します。
```js
expand('{'.repeat(3200) + 'a,b' + '}'.repeat(3200))
// RangeError: Maximum call stack size exceeded
```
深度3,125でクラッシュします。入力は約**6.25 KB**です。これは、このパッケージに対する既知の最もスタック枯渇を引き起こしやすいペイロードです。これは、GHSA-6j4f-fj2g-mc7p(29 KB)の入力の約4分の1、およびminimatchの`MAX_PATTERN_LENGTH`(65,536)の約10分の1です。
### `max`と`maxLength`が効果がない理由
どちらのクラッシュも、結果セットが大きくなる前に、サブ展開への再帰中に発生します。ペイロードはほとんど出力を生成しません。単一のセットの場合、2つの結果しか生成されないため、どちらの制限も制限要因にはなりません。`expand(payload, { max: 1, maxLength: 1 })`でも、スタックオーバーフローが発生します。
### 影響
`expand()`関数に、直接または`minimatch`や`glob`といったライブラリを通じて、ユーザーが提供したグローバルパターンとして、信頼できない文字列が渡されると、アプリケーションがクラッシュする可能性があります。Node.jsでは、アプリケーションが捕捉しない`RangeError`が発生するとプロセスが終了するため、サーバーがユーザーからの入力をグローバル展開する場合、リモートからの認証なしでのサービス拒否攻撃を受ける可能性があります。
影響は可用性のみです。コードの実行やデータの漏洩はありません。
### 影響を受けるバージョン
1.1.18、2.1.4、3.0.6、および5.0.9で影響が確認されました。すべてのバージョンで、ほぼ同一の深さの箇所に問題が発生しています(単一のセットでは3,125、カンマを含む場合は3,907~4,102)。これは、最近の修正によるものではなく、その問題はそれ以前から存在していました。
### 修正
`expand_()`関数に`maxDepth`という上限(デフォルトは`EXPANSION_MAX_DEPTH`)が設定されました。この上限を超えると、グループは展開されないものとして扱われ、そのまま返されます。これは、展開できないグループを既にそう処理しているパーサーの動作と一致しています。既存の`max`や`maxLength`の上限と同様に、エラーを発生させるのではなく、値を切り捨てることで、`expand()`関数はどのような入力に対してもエラーを発生させないように設計されています。
デフォルト値は、現実的なネストの深さよりも高く、クラッシュする閾値よりもかなり低い値に設定されています。
影響を受けるパッケージ:
- npm (JavaScript) brace-expansion: 影響を受けるバージョンは4.0.0以上、5.0.11未満。5.0.11で修正されました。
- npm (JavaScript) brace-expansion: 影響を受けるバージョンは3.0.0以上、3.0.8未満。3.0.8で修正されました。
- npm (JavaScript) brace-expansion: 影響を受けるバージョンは2.0.0以上、2.1.6未満。2.1.6で修正されました。
- npm (JavaScript) brace-expansion: 影響を受けるバージョンは1.1.20未満。1.1.20で修正されました。