Modern Frontend CVEs

対象CVE: GHSA-g5vv-q72c-7j78

[要注意] @anephenix/hubに認証不要なDoS脆弱性(GHSA-g5vv-q72c-7j78)

@anephenix/hubライブラリに、認証不要なWebSocket接続によってサーバーのリソースが枯渇させられる可能性のある深刻なDoS脆弱性が発見されました。Node.jsでWebSocketサーバーを構築しているフロントエンドエンジニアは特に注意が必要です。

はじめに

近年、リアルタイム通信の需要が高まり、フロントエンドとバックエンドの連携においてWebSocketは不可欠な技術となっています。しかし、その実装方法によっては、深刻な脆弱性を引き起こす可能性があります。今回は、Node.js向けのWebSocketハブライブラリである`@anephenix/hub`で発見された、認証不要なサービス拒否(DoS)脆弱性(GHSA-g5vv-q72c-7j78)について、その詳細と対策を日本のフロントエンドエンジニアの皆さん向けに解説します。

この脆弱性は、バックエンドのリソース管理の不備に起因しますが、フロントエンドで利用するサービス全体の安定性に直結するため、ぜひ内容を理解し、適切な対応を検討してください。

脆弱性の概要と影響

この脆弱性(GHSA-g5vv-q72c-7j78)は、深刻度が高(High)と評価されており、共通脆弱性識別子(CVE)はまだ割り当てられていません。その核心は「認証不要なWebSocket RPCウェイターのリソース枯渇」にあります。

具体的には、`@anephenix/hub`サーバーがWebSocket接続を受け入れる際、接続ごとにクライアントIDを要求するためのポーリングループ(`setInterval`)を開始します。問題は、リモートクライアントがこの要求に応答しない場合(これは認証不要で簡単に実行可能)、このポーリングタイマーと関連するリクエストオブジェクトが、たとえWebSocket接続が閉じられた後も適切にクリーンアップされない点です。

その結果、攻撃者が多数のWebSocket接続を開き、サーバーからのRPCメッセージを意図的に無視することで、サーバーのメモリとCPUに無数のタイマーとヒープエントリが蓄積され続けます。これにより、サーバーはリソースを使い果たし、正当なクライアントからのアクセスに応答できなくなり、サービス拒否(DoS)状態に陥ります。

技術的な詳細:なぜリソースが枯渇するのか?

脆弱性の根本原因は、WebSocket接続が確立された際のRPC処理における不適切なリソース管理にあります。以下にその技術的なフローを説明します。

1. **WebSocket接続の受付**: `@anephenix/hub`は、`wss.on("connection")`イベントリスナーを通じて、認証なしで任意のWebSocket接続を受け入れます。(`src/lib/index.ts:269`)

2. **クライアントID要求**: 新しいWebSocket接続ごとに、デフォルトで`requestClientId({ ws, rpc })`が呼び出されます。(`src/lib/index.ts:262`)

3. **RPCリクエストの送信**: `requestClientId`内部で、`rpc.send({ ws, action: 'get-client-id' })`が呼び出され、クライアントID取得のためのRPCリクエストが発行されます。(`src/lib/clientId.ts:112`)

4. **リクエストの登録とポーリング開始**: `rpc.send`メソッドは、保留中のリクエストを`this.requests`に格納し、同時に`waitForReply`を呼び出します。この`waitForReply`が10ミリ秒ごとに`responses[]`をポーリングする`setInterval`を開始します。(`src/lib/rpc.ts:282`、`src/lib/rpc.ts:250`)

5. **クリーンアップロジックの欠如**: この`setInterval`は、対応する応答が届いた場合にのみ`clearInterval`が呼ばれて停止します。しかし、**クライアントからの応答がない場合のタイムアウト処理や、WebSocketソケットが閉じられた際の明示的なクリーンアップ処理が実装されていません**。`close`ハンドラはパブサブの購読解除のみを行い、保留中のRPCリクエストはキャンセルしません。

結果として、攻撃者がWebSocket接続を確立し、サーバーからの`get-client-id`リクエストに一切応答せずに接続を閉じると、サーバー側には応答を待ち続ける`setInterval`タイマーと関連するリクエストオブジェクトが残り続けます。これが大量に発生することで、システムリソースが徐々に枯渇していきます。

再現方法(PoC)の解説

提供されているPoCでは、この脆弱性が簡単に再現できることが示されています。PoCはDocker環境やPythonスクリプト、さらにはミニマルなNode.jsコードでも実行可能です。

基本的な手順は以下の通りです。

1. `@anephenix/hub`サーバーを起動する。

2. WebSocketクライアントからサーバーに接続する。

3. サーバーからの`get-client-id` RPCメッセージを**無視して応答しない**。

4. WebSocketソケットを閉じる。

5. サーバーの`hub.rpc.requests.length`を確認すると、ソケットが閉じられた後もリクエストが残っていることが確認できる。

このPoCにより、認証や特別な設定なしに、単に接続を開いてメッセージを無視するだけでサーバーのリソースがリークしていく様子が実証されます。攻撃者にとっては非常に容易な攻撃経路となります。

影響を受けるシステムと対策

この脆弱性は、`@anephenix/hub`ライブラリの特定のバージョン(報告時点ではv0.2.15以前)を、デフォルト設定で使用しているNode.jsアプリケーションに影響を与えます。ネットワーク経由でアクセス可能な`@anephenix/hub`サーバーは、認証不要なDoS攻撃の標的となる可能性があります。

1. **ライブラリのアップデート**: 最も効果的な対策は、この脆弱性が修正された`@anephenix/hub`の最新バージョンへ速やかにアップデートすることです。ライブラリの公式リポジトリやnpmで、セキュリティパッチが適用されたバージョンがリリースされているかを確認し、更新してください。

2. **緩和策の検討**: すぐにアップデートできない場合は、以下のような緩和策を検討してください。

* **リバースプロキシでの接続数制限**: NginxやHAProxyなどのリバースプロキシを導入し、一定時間内の新規WebSocket接続数や同時接続数に制限を設けることで、大量の悪意ある接続を緩和できる可能性があります。

* **WAF/IPSによる異常検知**: Web Application Firewall (WAF) や Intrusion Prevention System (IPS) を導入し、異常な接続パターン(例えば、接続後に通信が途絶える、短時間に大量の接続と切断を繰り返すなど)を検知・ブロックするルールを設定します。

* **レートリミットの導入**: アプリケーションレベルで、IPアドレスごとの接続頻度やアクティビティに対するレートリミットを導入することを検討してください。

フロントエンドエンジニアへの示唆

フロントエンドエンジニアの皆さんにとって、この種のバックエンド脆弱性は一見直接関係ないように思えるかもしれません。しかし、バックエンドの安定性は、フロントエンドが提供するユーザー体験に直接影響します。

今回の件から、以下の点を意識することが重要です。

1. **依存ライブラリの定期的なチェック**: 自身が関わるプロジェクトのバックエンドが使用しているnpmパッケージやその他のライブラリについて、セキュリティ情報を定期的にチェックする習慣をつけましょう。GitHub Advisory Database(GHSA)やSnykなどのツールが役立ちます。

2. **WebSocket通信設計への理解**: WebSocketを用いたリアルタイム通信を設計・利用する際は、バックエンドのリソース管理(接続、切断、タイムアウト、エラーハンドリング)がどのように行われているか、基本的な仕組みを理解しておくことが重要です。フロントエンドからの異常な挙動がバックエンドにどのような影響を与えるかを想定できるようになりましょう。

3. **セキュリティ意識の向上**: 開発チーム全体でセキュリティに対する意識を高め、コードレビューや設計段階からセキュリティを考慮した議論を行うことが、堅牢なアプリケーション構築には不可欠です。

まとめ

`@anephenix/hub`における認証不要なDoS脆弱性は、WebSocketを利用したリアルタイムアプリケーションが直面しうる典型的なリソース管理の課題を浮き彫りにしました。この脆弱性は容易に悪用され、サービス停止につながる可能性があるため、対象となるライブラリを使用している場合は、速やかに修正版へのアップデートを強く推奨します。

私たちフロントエンドエンジニアも、バックエンドのセキュリティ脆弱性がユーザー体験に与える影響を理解し、安全なウェブサービス提供のために、常に最新のセキュリティ情報をキャッチアップし、積極的に対策に取り組んでいきましょう。

← ブログ一覧に戻る