Node.js向けサンドボックス「isolated-vm」に重大な脆弱性、ホスト脱出やRCEのおそれ
要点
-
Node.jsでJavaScriptを隔離実行するライブラリ「isolated-vm」に、サンドボックスを突破できる重大な脆弱性が判明した。
-
データ転送クラス「ExternalCopy」の型混同に起因し、ホストプロセスのメモリ破損やリモートコード実行(RCE)につながるおそれがある。
-
バージョン7.0.0以前の全バージョンが影響を受け、修正版となるバージョン6.2.0および7.0.1がすでに公開されている。
-
原因はV8エンジンの分離機構そのものではなく、境界間でデータを仲介するC++のバインディング層の不備と報告されている。
-
Node.js環境で信頼できないJavaScriptコードを安全に隔離実行するためのライブラリ「isolated-vm」において、サンドボックスを突破してホストプロセスに干渉できる重大な脆弱性が明らかになった。セキュリティ企業Endor Labsの研究者が発見・報告したもので、悪用された場合にはホストプロセスのクラッシュや、ホスト環境における任意のコード実行(RCE)につながる可能性があるという。
広く使われる隔離実行ライブラリ「isolated-vm」
「isolated-vm」は、GoogleのJavaScriptエンジン「V8」が備える独立インスタンス「V8 Isolate」を利用し、複数のサンドボックス環境を並行して動かすオープンソースライブラリだ。各Isolateは独立した状態と専用のヒープ(メモリ領域)を持つため、データを共有せず相互干渉を防ぐ設計となっている。
同ライブラリは開発者の間で広く利用されており、GitHub上では2,900以上のスターと190のフォークを獲得しているほか、npmパッケージのダウンロード数は直近1週間で約100万件に達していた。
影響範囲と修正バージョン
今回の脆弱性は「GHSA-864f-rcv7-6rh4」として公開されている(現時点でCVE識別子は未採番)。影響を受けるのはバージョン7.0.0以前(7.0.0を含む)のすべてのバージョンだ。
すでに修正版となるバージョン6.2.0および7.0.1がリリースされており、開発環境などでisolated-vmを導入しているユーザーに対して最新版への更新が呼びかけられている。なお、悪意ある攻撃者による悪用を防ぐため、完全なエクスプロイト(実証コード)の詳細は非公開とされている。
データ転送を担う「ExternalCopy」の型混同
V8 Isolateは独立したヒープを管理するため、メインスレッドからゲスト側のIsolateへ直接JavaScriptオブジェクトを渡すことができない。そのためisolated-vmでは、ホスト側でオブジェクトをシリアライズ(データ変換)し、ゲスト側でデシリアライズして安全に渡すためのクラス「ExternalCopy」を提供している。
Endor Labsの研究者Cristian-Alexandru Staicu氏によると、今回の脆弱性はこのExternalCopyが「transferList」オプションを処理する際に発生する型混同(Type Confusion:想定外の型として処理してしまう問題)に起因するという。サンドボックス内で動作するコードがこの不備を突くことで、ホストプロセスのメモリを破壊することが可能になる。
実証された影響:メモリ破壊からRCEまで
Staicu氏の報告によると、ホストがサンドボックスに機能を付与する標準的な手段である単一の「ivm.Reference」さえあれば、攻撃を成立させられることが実証された。特定のアドレスでのクラッシュからホストプロセスの制御フロー(実行順序)の乗っ取りへと攻撃を段階的にエスカレーションさせ、ゲスト環境からホスト環境への完全なサンドボックス脱出が可能だという。
プロジェクトメンテナーのMarcel Laverdet氏がアドバイザリで説明した実証済みの影響は以下の通りだ。
- 最小の影響: ivm.Referenceを付与されたゲスト環境から、セグメンテーション違反(SIGSEGV)によるホストプロセスのクラッシュを確実に引き起こすサービス運用妨害(DoS)。
- 最大の影響: ホストプロセスの制御フローの乗っ取り、すなわちホスト環境における潜在的なリモートコード実行(RCE)。
これにより、本来ライブラリが担保すべき信頼の境界線が損なわれると指摘されている。
分離機構ではなく「バインディング層」の不備
Staicu氏は、今回の問題についてV8エンジンのIsolate境界自体が破られたわけではない点を強調している。Isolateという分離機構そのものは堅牢に機能していたが、その境界を跨いで値をやり取り(マーシャリング)するC++のグルーコード(連携層)に不備が存在していたという。健全な構成要素を用いていても、それを包むバインディング層の欠陥によってシステム全体の安全性が脅かされた事例となった。