Modern Frontend CVEs

対象CVE: CVE-2026-47135

[重要セキュリティ警告] vm2サンドボックス脱出脆弱性 (GHSA-m5q2-4fm3-vfqp) の詳細と対策

Node.js環境で信頼できないコードを安全に実行するためのライブラリvm2に、サンドボックスを脱出しホスト側のロジックを乗っ取られる深刻な脆弱性が発見されました。高深刻度と評価されており、早急なアップデートが必要です。

はじめに:vm2とは何か? フロントエンドとの関連性

フロントエンドエンジニアの皆さん、こんにちは。今回はNode.js環境におけるサンドボックスライブラリ「vm2」に関する重大なセキュリティ脆弱性について解説します。

vm2は、Node.jsの内部で信頼できないJavaScriptコードを安全な隔離環境(サンドボックス)で実行するために広く使われているライブラリです。例えば、ユーザーがアップロードしたカスタムスクリプトを実行するようなプラットフォーム、サーバーサイドで動的にコードを評価する機能、あるいはプラグイン機構など、さまざまなケースで活用されることがあります。

直接フロントエンドコードに組み込むことは稀ですが、Next.jsやNuxt.jsなどのSSR/SSG環境のバックエンド部分、あるいはCI/CDパイプラインでのスクリプト実行環境など、Node.jsが関わるシステム全体でvm2が使用されている可能性があります。そのため、間接的に皆さんの開発するアプリケーションやシステムに影響を及ぼす可能性があるため、この脆弱性について理解しておくことは非常に重要です。

脆弱性の概要:GHSA-m5q2-4fm3-vfqp / CVE-2026-47135とは?

今回発見された脆弱性 (GHSA-m5q2-4fm3-vfqp / CVE-2026-47135) は、vm2のバージョン3.11.2以前のすべての3.x系バージョンに影響を与えます。この脆弱性は「サンドボックス脱出(Sandbox Escape)」を可能にするものであり、サンドボックス内で実行されている隔離されたコードが、本来アクセスを許されていないホスト(メインアプリケーション)側の機能やロジックを不正に操作できてしまうという深刻な問題です。

これにより、ホスト側の重要な処理の挙動が乗っ取られ、意図しないデータや結果が返される恐れがあります。深刻度は「High」と評価されており、早急な対応が求められます。

技術的詳細:なぜサンドボックスから脱出できるのか?

この脆弱性は主に二つの要因が組み合わさって発生します。

Node.jsには、内部で特殊な目的のために使われる「シンボル」(`Symbol.for`で取得できる識別子)がいくつか存在します。vm2は本来、サンドボックス内から触らせたくない特定のNode.js内部シンボルをブロックする仕組みを持っていました。しかし、この脆弱性では、例えば関数の非同期化に使われる`util.promisify`の挙動をカスタマイズするための`nodejs.util.promisify.custom`といった重要なシンボルが、サンドボックス内で「本物」として取得できてしまいました。これらのシンボルは、異なる実行コンテキスト(クロスレルム)間で特殊な振る舞いを引き起こす可能性があり、悪用される危険性があります。

vm2は、サンドボックスがホスト側のオブジェクトを「読み取ろう」とする際には、危険なシンボルをチェックする機構を備えていました。しかし、`set`(プロパティ設定)、`defineProperty`(プロパティ定義)、`deleteProperty`(プロパティ削除)といった「書き込み」操作においては、このチェックが全く行われていませんでした。このため、サンドボックス内のコードは、取得できてしまった危険なNode.js内部シンボルを使って、ホスト側のオブジェクトのプロパティを自由に設定、変更、削除できてしまいます。

例えば、ホスト側が提供する関数`hostFn`があるとします。サンドボックス内の悪意のあるコードは、この`hostFn`にアクセスし、`Symbol.for('nodejs.util.promisify.custom')`シンボルを使って、`hostFn`が`util.promisify`された際の挙動を、サンドボックスが制御する悪意のある関数に書き換えることができます。結果として、ホスト側で`util.promisify(hostFn)`が呼ばれると、本来の処理ではなく、サンドボックスが仕込んだ偽の処理が実行され、予期せぬ結果が返されることになります。

この脆弱性による直接的なリモートコード実行(RCE)は発生しないとされています。しかし、サンドボックスがホスト側の重要なロジックや振る舞いを制御できるようになるため、深刻な影響があります。例えば、ホスト側のストリーム処理における型チェックが迂回されたり、データベースへのデータ書き込みの整合性が損なわれたりする可能性も考えられます。

影響を受けるバージョンと確認方法

この脆弱性の影響を受けるのは、vm2のバージョン3.11.2以前のすべての3.x系バージョンです。

ご自身のプロジェクトでvm2を使用しているか、または間接的に依存しているかを確認するには、`package.json`や`yarn.lock`、`package-lock.json`ファイルを開いてvm2のバージョンを確認してください。

ターミナルで以下のコマンドを実行することでも確認できます:

`npm list vm2` または `yarn why vm2`

推奨される対策:今すぐできること

最も効果的かつ推奨される対策は、**vm2を直ちに最新バージョン(3.11.3以降)にアップデートすること**です。最新バージョンでは、この脆弱性に対する修正が適用されています。

アップデートコマンド:

`npm install vm2@latest` または `yarn upgrade vm2 --latest`

もし何らかの理由で直ちにアップデートできない場合でも、パッチ内容から以下の修正点が示唆されていますが、これらの内部的な修正はvm2のコアロジックに関わるため、基本的には公式アップデートを強く推奨します。自己修正は予期せぬ副作用を生む可能性があります。

1. **`setup-sandbox.js`の修正**: `Symbol.for`関数において、`nodejs.`で始まるすべてのシンボルをブロックするように変更します。

2. **`bridge.js`の修正**: オブジェクトの書き込み操作(`set`, `defineProperty`, `deleteProperty`)を行うトラップに、危険なクロスレルムシンボルをチェックする機能を追加します。

3. **`setup-sandbox.js`の修正**: `isDangerousSymbol`や`Object.getOwnPropertyDescriptors`、`Object.assign`のオーバーライドなど、他の関連するフィルターもすべての危険なシンボルに対応するように同期させます。

フロントエンドエンジニアとしての学びと注意点

今回の脆弱性は、サンドボックス環境の設計と実装の難しさ、そして依存ライブラリのセキュリティ対策の重要性を改めて示しています。

• **依存ライブラリの定期的なチェック**: `npm audit`や`yarn audit`を定期的に実行し、既知の脆弱性がないか確認する習慣をつけましょう。

• **サンドボックスの限界理解**: サンドボックスは完璧なセキュリティを提供するものではなく、常に潜在的な抜け穴が存在しうるという認識を持つことが重要です。

• **Node.jsの内部動作への理解**: Node.jsの内部シンボルやプロキシといったJavaScriptの高度な機能がセキュリティにどのように影響するかを知ることは、より堅牢なシステムを構築するために役立ちます。

まとめ

vm2のサンドボックス脱出脆弱性は、Node.js環境におけるセキュリティの基礎を揺るがす重大な問題です。ご自身のプロジェクトでvm2を使用している場合は、直ちにバージョンアップを実施し、安全な状態を確保してください。今回の件を教訓に、よりセキュリティ意識の高い開発を心がけましょう。

← ブログ一覧に戻る