[緊急警告] vm2のサンドボックスエスケープ脆弱性 (CVE-2026-47210) – Node.js 26ユーザーは特に注意!
はじめに
Node.js環境で信頼できないJavaScriptコードを安全に実行するために広く利用されているサンドボックスライブラリ`vm2`に、非常に危険度の高いサンドボックスエスケープ脆弱性 (CVE-2026-47210 / GHSA-6j2x-vhqr-qr7q) が発見されました。この脆弱性を悪用されると、攻撃者はサンドボックスを突破し、ホスト環境で任意のコードを実行し、システムを完全に制御できてしまう可能性があります。特に、WebAssembly JSPI (JavaScript Promise Integration) 機能が有効なNode.js 26を使用している環境では、緊急度の高い対応が求められます。
vm2とは?なぜサンドボックスが必要なのか?
`vm2`は、Node.js環境で独立した安全なJavaScript実行環境(サンドボックス)を提供するライブラリです。例えば、ユーザーがアップロードしたスクリプトを実行するWebサービス、プラグインシステム、あるいは特定のテスト環境などで、ホストシステムへの悪影響を心配することなくコードを実行したい場合に利用されます。サンドボックスは、内部のコードが外部のファイルシステムやネットワーク、システムコマンドにアクセスできないようにすることで、セキュリティ境界としての役割を果たします。
深刻なサンドボックスエスケープ脆弱性 (CVE-2026-47210) の概要
今回発見された脆弱性は、`vm2`のセキュリティ境界を完全に無効化し、攻撃者がサンドボックスの外にあるホスト環境で任意のコードを実行できるようにするものです。深刻度は`critical`に分類されており、悪用された場合の影響は甚大です。
具体的には、`vm2`内で実行される信頼できないJavaScriptコードが、`vm2`が動作しているホストプロセス(例えばNode.jsサーバー)上で任意のOSコマンドを実行できるようになります。これにより、攻撃者はホストプロセスの権限でファイル操作、機密情報窃取、さらにはシステム全体の乗っ取りまでも可能になります。
脆弱性の詳細と技術的なメカニズム
この脆弱性は、以下の特定の条件が組み合わさることで発生します。
1. `vm2`で`async`サポートが有効になっている。
2. Node.jsランタイムでWebAssembly JSPI(JavaScript Promise Integration)機能(`WebAssembly.promising`や`WebAssembly.Suspending`など)が公開されている。特にNode.js 26で確認されています。
通常、`vm2`はPromiseオブジェクトの挙動を厳密に監視し、「Promise-species hardening」と呼ばれる対策を施すことで、サンドボックスからの脱出を防いでいます。しかし、WebAssembly JSPIが関与するPromiseが`.finally()`メソッドを呼び出す際に、この堅牢化がバイパスされてしまうことが判明しました。
問題の核心は、JSPI絡みのPromiseが`.finally()`を呼び出した際に、ホスト環境で生成されたPromise拒否(rejection)オブジェクトが、攻撃者が制御できるサンドボックス内のロジックに予期せず露出してしまう点にあります。攻撃者は、この露出した拒否オブジェクトの「コンストラクタチェーン」を悪用することで、サンドボックスの外にあるホストの`process`オブジェクト(Node.jsのグローバルオブジェクト)にアクセスできるようになります。
一度`process`オブジェクトにアクセスしてしまえば、攻撃者は`child_process`モジュールなどを利用して、ホスト環境上で任意のOSコマンドを自由に実行できるようになります。興味深いことに、この脆弱な挙動は`.finally()`との組み合わせでのみ発生し、`.then()`や`.catch()`では`vm2`の通常のセキュリティ処理が適用されるとのことです。この詳細な挙動は、脆弱性の巧妙さを示しています。
影響を受けるアプリケーションと実質的なリスク
**影響を受けるアプリケーション:**
攻撃者によって制御されうるJavaScriptコードを`vm2`サンドボックス内で実行し、`vm2`をセキュリティ境界として信頼しているすべてのアプリケーションが対象です。これには、ユーザーがスクリプトを記述できるSaaSプラットフォーム、カスタムロジックを実行するバックエンドサービス、CI/CD環境でのスクリプト実行などが含まれます。
**特に影響を受ける環境:**
WebAssembly JSPI機能が有効なNode.jsランタイム(特にNode.js 26)を使用している場合、脆弱性の影響を強く受けます。Node.js 26を使用しており、`vm2`で非同期処理を有効にしているシステムでは、最も緊急度の高い対応が必要です。
**実質的な影響:**
1. **ホストプロセス上での任意のコマンド実行:** 攻撃者はOSコマンドを実行し、システムのファイル削除、プログラム起動、ユーザーアカウント作成など、あらゆる操作を実行できます。
2. **ホストプロセスがアクセス可能なファイルの読み書き:** 機密設定ファイル、データベースのバックアップ、ユーザーデータなど、システム上のあらゆるファイルを読み取ったり、改ざんしたりする可能性があります。
3. **機密情報(トークン、認証情報、アプリケーションデータ)の窃取:** 環境変数、APIキー、データベースの接続情報など、アプリケーションが利用する機密情報が盗まれる可能性があります。
4. **`vm2`の分離機能に依存するサービスの完全な乗っ取り:** サンドボックスの目的が完全に破壊され、サービス全体が攻撃者に支配されます。
いますぐ取るべき対策と推奨事項
この深刻な脆弱性からシステムを保護するために、以下の対策を速やかに実行してください。
`vm2`の公式修正がリリースされ次第、**速やかに最新バージョンへアップデートしてください**。これは最も直接的で効果的な対策です。アップデート情報については、`vm2`のGitHubリポジトリや公式アナウンスを定期的に確認してください。
例: `npm install vm2@latest`
WebAssembly JSPI機能が有効なNode.jsバージョン(Node.js 26)の使用を避けるか、可能であればJSPI機能を無効化することを検討してください。Node.jsの起動オプションなどでこれを制御できる場合がありますが、アプリケーションへの影響も考慮する必要があります。
アップデートが難しい場合や、二重の防御として、`vm2`をセキュリティ境界として利用する設計自体を見直すことも重要です。信頼できないコードを隔離する他の手段(例えば、Dockerコンテナなどのプロセスレベルの分離、軽量な仮想マシンなど)を検討してください。
`vm2`が動作するNode.jsプロセスは、必要最小限の権限で実行されるように徹底してください。これにより、万が一サンドボックスが破られても、攻撃者ができる範囲を限定することができます。
まとめ
`vm2`の深刻なサンドボックスエスケープ脆弱性 (CVE-2026-47210) は、特にNode.js 26とWebAssembly JSPIの組み合わせにおいて、ホストシステムを完全に侵害する非常に高いリスクを伴います。日本のフロントエンドエンジニアの皆さんも、ビルドツールや特定のバックエンド処理で`vm2`を使用している場合は、この情報を真剣に受け止め、**速やかに推奨される対策を講じてください**。セキュリティは常に変化し続けるため、最新の情報に注意し、システムの安全性を確保しましょう。