[解説] vm2のサンドボックスエスケープ脆弱性 (CVE-2026-93605) に潜む危険と対策
はじめに
`vm2`は、Node.js環境において信頼できないコードを安全に実行するためのサンドボックスを提供する人気のあるライブラリです。開発者は、プラグインシステム、スクリプト実行環境、あるいはSSR(サーバーサイドレンダリング)の一部として、ユーザー提供コードや外部ライブラリを隔離して実行するために`vm2`を利用することがあります。
しかし、このサンドボックスの「安全性」の前提を根底から覆す、極めて深刻な脆弱性(GHSA-pq68-rvw4-xp4r / CVE-2026-93605)が発見されました。本記事では、この脆弱性の詳細、その影響、そしてフロントエンドエンジニアが取るべき対策について解説します。
脆弱性の概要
この脆弱性は、`vm2`の`NodeVM`におけるサンドボックスエスケープであり、深刻度(Severity)は「**critical**」と評価されています。影響を受けるのは`vm2`のバージョン**3.12.1未満**です。
具体的には、`vm2`のサンドボックス内で実行されるコードが、通常は隔離されるべきホストシステム(Node.jsプロセスが動作している環境)の`child_process`モジュールにアクセスできてしまうという問題です。これにより、サンドボックス内の攻撃者は、ホストシステム上で任意のコマンドを実行することが可能になります。これは、サンドボックスの目的を完全に無効化する、究極のセキュリティリスクと言えるでしょう。
何が問題なのか? (技術的な詳細)
`vm2`の`NodeVM`には、ホストシステムへのアクセスを防止するための`DANGEROUS_BUILTINS`というデンジャーリスト(ブラックリスト)が存在します。このリストには、`module`、`worker_threads`、`cluster`、`vm`、`process`など、ホストシステムへの影響が大きいと見なされるNode.jsの組み込みモジュールが多数含まれています。
問題は、**この`DANGEROUS_BUILTINS`リストから`child_process`モジュールが意図せず漏れていたこと**にあります。
`vm2`の利用者が`NodeVM`を初期化する際に、`require:{builtin:['*']}`(すべての組み込みモジュールを許可する設定)や、明示的に`builtin:['child_process']`を設定した場合、`child_process`がデンジャーリストで適切にブロックされず、サンドボックス内で`require('child_process')`が成功してしまいます。
提供された情報によると、`lib/builtin.js`のコード構造において、`child_process`が`DANGEROUS_BUILTINS`に含まれておらず、結果として`isDangerousBuiltin('child_process')`が`false`を返すため、`['*']`オプションを選択した場合でも`child_process`が許可されてしまうことが指摘されています。これは、`cluster`モジュールが「`cluster.fork()`が攻撃者によって制御されるコードを実行するホスト子プロセスを生成する」という理由でブロックされているにもかかわらず、より直接的にコマンド実行を可能にする`child_process`が漏れていたという、内部的な不整合でもあります。
一度`child_process`がロードされてしまえば、サンドボックス内のスクリプトは`require('child_process').execSync('id').toString();`のようなコードを通じて、ホストシステム上で任意のシェルコマンドを実行し、その結果を取得できます。これは、サンドボックス内のコードが「完全に隔離されている」という前提を破壊します。
脆弱性の影響
この脆弱性の影響は極めて甚大です。サンドボックスの目的は、信頼できないコードが悪意のある操作を行うことを防ぐことですが、この脆弱性はその防壁を完全に打ち破ります。
* **完全なホストRCE (Remote Code Execution)**: 攻撃者はサンドボックスを完全に脱出し、`vm2`インスタンスが動作しているホストシステム上で任意のコマンドを実行できます。これには、機密情報の窃取、システムの改ざん、バックドアの設置、他のサーバーへの攻撃の踏み台化などが含まれます。
* **データ漏洩とシステム破壊**: データベースのクレデンシャルやAPIキーなどの環境変数を読み取ったり、ファイルシステムを操作したりすることが可能になります。
* **サービス停止**: 悪意のあるコマンドによってサービスを停止させられる可能性もあります。
特に、ユーザーが提供したJavaScriptコードを実行するようなサービス(例えば、コード評価ツール、オンラインIDE、カスタムスクリプト実行機能を持つプラットフォーム)や、ビルドプロセスの一部で外部ライブラリをサンドボックス化して実行している環境などは、直接的な標的となり得ます。
対策と対応
この深刻な脆弱性に対し、フロントエンドエンジニアとして迅速に対応することが求められます。
1. **`vm2`をバージョン`3.12.1`以上にアップデートする**: これが最も直接的かつ効果的な対策です。最新バージョンではこの脆弱性が修正されています。プロジェクトで使用している`vm2`のバージョンを確認し、直ちにアップデートを計画・実行してください。 ```bash npm install vm2@latest # または yarn upgrade vm2 ``` `package.json`の`dependencies`や`devDependencies`も更新し、`package-lock.json`や`yarn.lock`も確実に更新されていることを確認しましょう。
2. **`require`オプションの見直し**: もし、`NodeVM`の初期化時に`require:{builtin:['*']}`のような広範な許可を設定している場合は、その設定を直ちに見直してください。必要最小限の組み込みモジュールのみを許可する「最小権限の原則」に従うべきです。 `child_process`モジュールが必要ない場合は、明示的に禁止することも検討できます(ただし、バージョン3.12.1未満ではこの脆弱性の影響を受けるため、アップデートが最優先です)。
3. **サンドボックスで実行するコードの信頼性評価**: 信頼できないソースから提供されたコードをサンドボックス内で実行する際は、常に最大限の注意を払う必要があります。`vm2`のようなサンドボックスライブラリはセキュリティを強化しますが、完璧ではありません。定期的な脆弱性情報のチェックが不可欠です。
まとめ
`vm2`のサンドボックスエスケープ脆弱性 (GHSA-pq68-rvw4-xp4r / CVE-2026-93605) は、`child_process`モジュールのデンジャーリストからの漏れにより、ホストシステムでのRCEを可能にする極めて深刻な問題です。
フロントエンドエンジニアが直接`vm2`をプロダクション環境で利用するケースは少ないかもしれませんが、ビルドツール、テスト環境、CI/CDパイプライン、あるいは社内ツールなどで間接的に利用されている可能性も考慮し、開発・運用しているシステム全体で`vm2`の利用状況を確認し、バージョン`3.12.1`以上への速やかなアップデートを強く推奨します。
セキュリティは常に進化する脅威との戦いです。最新の情報を常に追いかけ、適切な対策を講じ続けることが、安全なシステムを維持するために不可欠です。