SandboxJSにおける極めて深刻なサンドボックス脱出の脆弱性(CVSS 10.0)への緊急対応ガイド

Tech

[STP-REPORT-2024-VULN-003] [CATEGORY: VULNERABILITY_ADVISORY] [PRIORITY: CRITICAL (CVSS 10.0)] [TARGET: SandboxJS / Node.js Runtime Environments]

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

SandboxJSにおける極めて深刻なサンドボックス脱出の脆弱性(CVSS 10.0)への緊急対応ガイド

【脅威の概要と背景】

JavaScript実行環境を分離するライブラリ「SandboxJS(および類似のvm2等)」において、合計4件のクリティカルな脆弱性が特定されました。これらは、攻撃者がサンドボックスの制限を完全に回避し、ホストOS上で任意のコマンドを実行できる(RCE)もので、CVSS v3.1スコアは最大値の10.0と評価されています。プロトタイプ汚染やProxyオブジェクトの悪用を突いた手法が確認されており、信頼できないコードを実行するすべての環境が対象となります。

【攻撃シナリオの可視化】

攻撃者がサンドボックスを突破し、ホストシステムの制御を奪取するまでのプロセスを以下に示します。

graph TD
    A["攻撃者: 悪意あるJSを送信"] -->|入力値として注入| B["SandboxJS実行環境"]
    B -->|Proxy/Errorオブジェクトの悪用| C{"サンドボックス脱出"}
    C -->|グローバルコンテキストへのアクセス| D["ホストOSのprocessオブジェクト奪取"]
    D -->|child_process.exec| E["任意コマンド実行: RCE"]
    E -->|機密情報奪取/ランサムウェア| F["システム完全沈黙"]

【安全な実装と設定】

脆弱なサンドボックス実装と、安全性を高めた代替案の対比です。

1. 脆弱な実装例 (SandboxJS / vm2 等)

信頼できないコードを、適切な分離なしにライブラリのみに頼って実行している場合、プロトタイプ汚染により脱出を許します。

// ❌ 脆弱な例:ライブラリの論理的な分離のみに依存
const { Sandbox } = require('sandboxjs'); // または vm2
const sb = new Sandbox();
const untrustedCode = `this.constructor.constructor('return process')().mainModule.require('child_process').execSync('id')`;
console.log(sb.run(untrustedCode)); 

2. 安全な代替案(多層防御による分離)

JavaScriptレベルのサンドボックスではなく、V8のIsolate機能を利用したライブラリへの移行、およびOSレベルのサンドボックス(gVisor, Docker, WebAssembly等)の併用が強く推奨されます。

// ✅ 改善策:isolated-vm 等のより厳格な分離ライブラリの使用
const ivm = require('isolated-vm');
const isolate = new ivm.Isolate({ memoryLimit: 128 });
const context = isolate.createContextSync();

// 最小限の権限のみを与え、ホストのprocess等は渡さない
const script = isolate.compileScriptSync('1 + 1'); 
script.runSync(context);

// さらに、実行プロセス自体をOSレベルの低い権限(User Namespace等)で実行する

【検出と緩和策】

検出ポイント

  • EDR/SIEM: Node.jsプロセスが予期しない child_processsh, cmd.exe, curl 等)をスポーンしていないか監視。

  • 静的解析 (SAST): コード内で eval(), new Function(), または脆弱なバージョンのサンドボックスライブラリを使用している箇所を特定。

短期的な緩和策(Workaround)

  1. ライブラリの廃止と移行: vm2 等、既にメンテナンスが終了し脆弱性が放置されているライブラリは直ちに削除し、isolated-vm や WebAssembly (Wasm) ベースの実行環境へ移行する。

  2. 実行時制限: LD_PRELOADseccomp を用いて、Node.jsプロセスが発行できるシステムコールを制限する。

  3. ネットワーク分離: サンドボックス実行プロセスからの外部アウトバウンド通信をFirewallで完全に遮断する。

【実務上の落とし穴】

  • 可用性への影響: 強固な分離(例:Dockerコンテナを毎回立ち上げる等)に切り替えた場合、実行オーバーヘッドが大幅に増加し、サービスのレスポンス性能が低下する可能性があります。

  • 誤検知のリスク: 開発ツールや正規の運用スクリプトが内部で child_process を利用している場合、一律の制限によって運用監視ツールが動作しなくなることがあります。

  • 依存関係の連鎖: 自身のプロジェクトで直接使っていなくても、依存しているサードパーティライブラリが内部で脆弱なサンドボックスを使用しているケース(Transitive Dependency)が多く見られます。

【まとめ:今すぐ実施すべき3項目】

  1. インベントリ確認: npm list 等で、プロジェクト内(および依存先)に vm2sandbox などの脆弱なサンドボックスライブラリが含まれていないか即座に確認する。

  2. 実行環境の隔離: JSライブラリの論理的な隔離に頼らず、Docker、gVisor、Firecracker等の「コンテナ/マイクロVM」による物理的な分離を実装する。

  3. 最小権限の原則: サンドボックスを動かすユーザーアカウントから、書き込み権限やネットワーク権限を最小化する。


参考文献:

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました