Modern Frontend CVEs

対象CVE: CVE-2026-46679

[緊急警告] js-libp2pのGossipsubにおける深刻なメモリ枯渇脆弱性 (CVE-2026-46679)

js-libp2pのGossipsub機能に深刻なメモリ枯渇脆弱性が発見されました。これにより、外部からの悪意ある通信によってNode.jsアプリケーションがサービス停止に追い込まれるリスクがあり、早急な対策が必要です。

はじめに:js-libp2pの深刻なメモリ枯渇脆弱性(CVE-2026-46679)

皆さん、こんにちは。今回は、Web3領域やP2Pネットワークで広く利用されている`js-libp2p`ライブラリの`@libp2p/gossipsub`モジュールに発見された、非常に深刻な脆弱性(GHSA-4f8r-922h-2vgv / CVE-2026-46679)について解説します。この脆弱性は、Node.jsアプリケーションにおいて外部からの攻撃によってメモリが枯渇し、サービス停止に至る可能性があるため、特にフロントエンドのバックエンド処理やWeb3アプリケーション開発に携わる方は、その影響と対策を早急に理解しておく必要があります。

この脆弱性は何が問題なのか?

この脆弱性は「High」という高い深刻度で評価されており、その名の通り、アプリケーションの可用性に直接的な脅威をもたらします。最も危険な点は、認証されていない**単一の悪意のあるユーザーが、短時間でターゲットとなるNode.jsプロセスをメモリ不足に陥らせ、サービスを停止させることが可能**である点です。さらに悪いことに、一度消費されたメモリはプロセスが再起動するまで回復しないため、繰り返し攻撃を受けると、システム全体のリソースが枯渇し、致命的な影響を与えかねません。

脆弱性のメカニズム:なぜメモリが枯渇するのか?

この深刻な問題は、`@libp2p/gossipsub`モジュールにおける以下の3つの設計上の問題が複合することで発生します。

**1. サブスクリプション数に上限がない**

メッセージデコード時、一つのRPCリクエストに含まれるサブスクリプションエントリーの数に制限が設けられていません。これにより、攻撃者はたった一つのリクエストで、実質的に無限のユニークなトピックをアプリケーションにサブスクライブさせることができます。

**2. トピック情報が無限に増加する**

受信したユニークなトピック文字列ごとに、ノード内部の`this.topics`というMapオブジェクトに新しいエントリが作成されます。このMapにはサイズ制限がなく、さらに各ピアが購読しているトピック数も追跡されないため、リクエストごとにメモリが際限なく消費されていきます。実際に、一つのリクエストで約89MBものメモリが消費され、CPUも約224ミリ秒ブロックされることが確認されています。これは、アプリケーションの応答性にも大きな影響を与えます。

**3. メモリリークの発生**

さらに深刻なのがメモリリークです。外部ユーザーが切断された後も、そのユーザーがサブスクライブしていたトピックに対応する空のメモリ領域(具体的には`Set`オブジェクト)が、`this.topics`Mapから削除されずに残ってしまいます。これにより、一度消費されたメモリはアプリケーションプロセスが停止するまで解放されず、攻撃が繰り返されるたびにメモリ枯渇が加速し、最終的には「Out Of Memory (OOM)」エラーでプロセスがクラッシュする事態を招きます。

影響を受ける条件とリスクシナリオ

この脆弱性は、`@libp2p/gossipsub`を**デフォルト設定で利用している全てのNode.jsアプリケーション**に影響を与えます。特に、外部からの接続を受け入れ、Pub/Sub機能を利用しているアプリケーションは要注意です。

具体的な例としては、イーサリアムのコンセンサスレイヤークライアントである**Lodestar**や、分散型ファイルシステムである**IPFSのpubsub機能**などが挙げられます。これらのWeb3関連アプリケーションは、P2Pネットワークの基盤として`js-libp2p`を利用していることが多いため、特に注意が必要です。

**具体的なリスクシナリオ:**

**サービスの可用性への深刻な影響(メモリ枯渇):** たった一人の攻撃者が約68MBのデータを送信するだけで、100Mbpsのネットワーク環境であれば、約5秒でNode.jsプロセスをメモリ不足でクラッシュさせることが可能です。一度クラッシュすると、メモリはプロセス再起動まで回復しません。

**サービスの可用性への深刻な影響(CPU負荷):** 大量のサブスクリプション処理により、Node.jsのイベントループが長時間ブロックされ、アプリケーション全体の応答性が著しく低下します。これにより、正常なユーザーからのリクエスト処理も滞り、サービスが実質的に機能停止状態に陥る可能性があります。

**対策の困難さ:** この脆弱性に対しては、既存のスコアベースの緩和策が効果を発揮しません。悪意のあるユーザーは何度でも攻撃を繰り返すことができ、システムを疲弊させ続けることが可能です。

補足として、`opts.allowedTopics`を設定することで、攻撃者ごとに許可されるトピック数を制限することはできますが、これによりメモリリークやCPU負荷の増大が完全に解決されるわけではない点に注意が必要です。

緊急対応を!推奨される対応策

この脆弱性への対応は非常に緊急性が高いため、以下のパッチ適用または設定変更を**早急に検討**してください。

根本的な解決策は、上記の3つのメカニズムによって引き起こされるメモリリークと無限のメモリ増加を防ぐことにあります。

**1. 空のSetの削除:**

アンサブスクライブ時やピア切断時に、そのピアが購読していたトピックに対応する`Set`オブジェクトが空になった場合、`this.topics`Mapからその`Set`を明示的に削除するようにコードを修正します。これにより、不要なメモリ領域が残り続けることを防ぎます。

具体的には、`handleReceivedSubscription`メソッド内でアンサブスクライブ処理を行った際に、Setが空になったらMapから削除するロジックを追加します。同様に、`removePeer`メソッド内でもピア削除後にSetが空になったらMapから削除する処理が必要です。

**2. ノード停止時のクリーンアップ:**

アプリケーションが停止する際に、`this.topics`Mapの内容を完全にクリアするように修正します。これにより、再起動時のクリーンな状態を保証し、万が一メモリリークが発生していたとしても、次のプロセス起動時に影響が持ち越されないようにします。

具体的には、`stop()`メソッド内で`this.topics.clear()`を呼び出すようにします。

これらの修正により、メモリリークを防ぎ、攻撃によるメモリ枯渇リスクを大幅に軽減できます。利用している`js-libp2p`のバージョンを確認し、公式が提供するパッチやアップデート情報に常に注意を払ってください。

まとめ

`js-libp2p`の`gossipsub`機能におけるメモリ枯渇脆弱性(CVE-2026-46679)は、Node.jsアプリケーションの可用性に深刻な影響を与える可能性があります。特にWeb3領域やP2Pネットワークを活用しているフロントエンドエンジニアの皆さんは、自身のプロジェクトがこの脆弱性の影響を受けないか確認し、早急な対策を講じる必要があります。

P2Pネットワークのセキュリティは常に進化しており、依存ライブラリの脆弱性情報は定期的にチェックする習慣をつけましょう。安全で堅牢なアプリケーション開発のために、常に最新の情報をキャッチアップし、適切なセキュリティ対策を実施していくことが重要です。

← ブログ一覧に戻る