[緊急警告] Node.jsサンドボックスライブラリvm2のCritical脆弱性(CVE-2026-92948)解説
はじめに:なぜフロントエンドエンジニアも知るべきなのか?
皆さんは「vm2」というライブラリをご存知でしょうか?これはNode.js環境で、信頼できないコードを隔離された(サンドボックス化された)環境で安全に実行するために使われる、人気の高いライブラリです。サーバーサイドでユーザーがアップロードしたスクリプトを実行したり、CI/CD環境でのコード評価、あるいはJavaScriptの評価エンジンとして利用されることがあります。直接触れる機会は少ないかもしれませんが、皆さんの開発しているWebアプリケーションのバックエンドや、開発ツール、CI/CDパイプラインの内部で間接的に利用されている可能性も十分にあります。
今回、このvm2に重大な(Critical)脆弱性が報告されました。この脆弱性を悪用されると、サンドボックスをすり抜けてホストOS上で任意のコードが実行されてしまう可能性があります。これは「サンドボックスエスケープ」と呼ばれる非常に危険な攻撃です。特にNode.js 24以降のバージョンを使用している環境では注意が必要です。
脆弱性の概要(CVE-2026-92948 / GHSA-qhwx-74w5-xhxq)
この脆弱性は、vm2がNode.js 24以降の環境で、`node:test`という組み込みモジュールをサンドボックスに明示的に許可している場合に発生します。攻撃者は、特別に細工したコードを使って`node:test`モジュールの`run()`メソッドを呼び出し、その際に`execArgv`という引数を悪用することで、サンドボックスの外で新たなNode.jsプロセスを起動し、ホスト環境で任意のJavaScriptコードを実行できてしまいます。
具体的な情報は以下の通りです。
<ul><li><b>脆弱性ID</b>: GHSA-qhwx-74w5-xhxq</li><li><b>CVE ID</b>: CVE-2026-92948</li><li><b>深刻度</b>: Critical</li><li><b>影響を受けるパッケージ</b>: `vm2`</li><li><b>影響を受けるバージョン</b>: `>=3.9.6, <=3.11.5`</li><li><b>再現が確認されたNode.jsバージョン</b>: `v24.18.0` (Node.js 24以降に限定)</li><li><b>設定条件</b>: `require: { builtin: ['node:test'], external: false }` のように、`node:test`が明示的に許可されている場合</li></ul>
技術的解説:なぜサンドボックスが破られるのか?
この脆弱性は、複数の要因が組み合わさって発生します。ポイントは以下の3点です。
Node.js 24以降では、`module.builtinModules`という組み込みモジュールリストに`node:test`が追加されました。これにより、vm2がこの新しい組み込みモジュールを認識するようになります。
vm2の内部処理では、`require()`されたモジュール名から`node:`プレフィックスが1つ取り除かれます。このため、サンドボックス内で攻撃者が`require('node:node:test')`と記述すると、vm2はこれを`node:test`と認識します。そして、もしvm2の設定で`builtin: ['node:test']`が許可されていれば、ホスト側の実際の`node:test`モジュールへの読み取り専用プロキシがサンドボックスに提供されます。
サンドボックスに公開された`node:test`モジュールの`run()`メソッドは、引数として`execArgv`を受け取ります。この`execArgv`は、テスト実行のために新しく起動されるNode.jsプロセスに渡されるコマンドライン引数です。攻撃者はこの`execArgv`に`--eval=<JavaScriptコード>`のような引数を指定することで、サンドボックスの外で起動されたNode.jsプロセスで任意のJavaScriptコードを実行できてしまうのです。
vm2は通常、`fs`や`child_process`といった危険なモジュールへのアクセスをブロックしますが、`node:test.run()`で起動されるプロセスは、vm2のサンドボックスとは完全に独立しているため、これらの制限が適用されません。
この脆弱性がもたらす影響
この脆弱性を悪用されると、攻撃者はサンドボックスの制限を完全に迂回し、vm2が動作しているホスト環境で、vm2を起動したユーザーの権限で任意のコードを実行できてしまいます。
これにより、以下のような深刻な影響が発生する可能性があります。
今すぐできる対策と推奨される対応
残念ながら、本記事執筆時点(脆弱性情報が公開された時点)では、vm2の修正版バージョンはまだリリースされていないようです。そのため、以下の対策を速やかに検討してください。
もしvm2の設定で`require: { builtin: ['node:test'], ... }`のように`node:test`を許可している場合は、直ちにこの設定を削除してください。これが最も直接的かつ効果的な対策です。サンドボックスには必要最小限の権限のみを与える「最小権限の原則」を徹底しましょう。
特にNode.js 24以降の環境でvm2を使用している場合、この脆弱性の影響を受ける可能性が高いです。vm2の利用方法や、サンドボックス内で実行するコードの信頼性について再評価してください。
vm2の開発チームは通常、迅速に脆弱性に対応します。今後のバージョンでこの脆弱性が修正されると予想されるため、公式のアナウンスやGitHubリポジトリを定期的に確認し、修正版がリリースされ次第、速やかにバージョンアップを行ってください。
もし`node:test`の機能の一部をサンドボックス内で利用する必要がある場合は、`node:test.run()`のような危険なAPIを直接公開しない、vm2の`mock`や`override`機能を使ってサンドボックスローカルなラッパーを提供することを検討してください。
まとめ
今回のvm2の脆弱性は、サンドボックス環境の設計と利用の難しさを示す典型的な例です。特にNode.js 24以降でvm2を使っており、`node:test`を明示的に許可している場合は、非常に危険な状態にある可能性があります。フロントエンドエンジニアの皆さんも、ご自身の関わるプロジェクトでNode.jsがサーバーサイドやビルドツール、CI/CDなどで利用されている場合、今回の脆弱性が間接的に影響を与える可能性がないか、ぜひ確認してみてください。
セキュリティは常に最新の情報をキャッチアップし、適切な対策を講じることが重要です。日頃から依存ライブラリのセキュリティ情報にも目を光らせ、安全な開発を心がけましょう。