SandboxJSにおけるサンドボックス脱出およびRCE脆弱性(CVSS 10.0)への緊急対策

Tech

tone_style: professional, technical, objective language: ja format: markdown audience: developers, infrastructure engineers, security administrators meta_tags: { “category”: “vulnerability_report”, “urgency”: “critical”, “technical_level”: “high” }

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

SandboxJSにおけるサンドボックス脱出およびRCE脆弱性(CVSS 10.0)への緊急対策

【脅威の概要と背景】

信頼できないJSコードを隔離実行するSandboxJSにおいて、ホストOS上での任意コード実行(RCE)を可能にする4件の脆弱性が判明。プロトタイプ汚染やProxyオブジェクトの悪用により、サンドボックス境界が完全に無効化されます(CVSS v3.1: 10.0)。

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

攻撃者がサンドボックス環境を突破し、最終的にホストサーバーの制御を奪取するまでのキルチェーンを以下に示します。

graph TD
    A["攻撃者: 悪意あるJSを送信"] --> B{"SandboxJS実行環境"}
    B --> C["脆弱性悪用: プロトタイプ汚染/Proxy迂回"]
    C --> D["サンドボックス脱出: ホストのConstructorへアクセス"]
    D --> E["任意コード実行: process.mainModule.requireを利用"]
    E --> F["ホストOSの制御奪取 / データ窃取"]
    F --> G["C2サーバーへの通信/永続化"]

【安全な実装と設定】

1. 脆弱な実装例(誤用例)

以下のコードは、信頼できないユーザー入力を直接サンドボックスに渡しており、今回発見された脱出手法に対して無防備です。

// 脆弱な例: 旧バージョンのSandboxJSを使用
const { Sandbox } = require('sandboxjs'); // v1.x などの脆弱なバージョン
const sb = new Sandbox();

// ユーザー入力が直接実行される
const userInput = "this.constructor.constructor('return process')().exit()"; 
sb.run(userInput, (err, result) => {
    console.log(result);
});

2. 安全な代替案(修正後の実装)

最新バージョンへのアップデートに加え、多層防御(Defense in Depth)を適用します。

// 対策例: アップデートと実行時制限の強化
const { Sandbox } = require('sandboxjs'); // 修正済み最新版(v2.x以上)を想定

// オプションで明示的に危険なグローバルオブジェクトを制限
const sb = new Sandbox({
    timeout: 500,        // 実行時間の制限
    memoryLimit: 128,   // メモリ使用量の制限
    forbiddenTokens: ['process', 'require', 'module', 'constructor'] // キーワード検知
});

// 入力値のサニタイズ(追加の緩和策)
function safeRun(input) {
    if (typeof input !== 'string' || input.length > 1000) {
        throw new Error("Invalid input");
    }
    return sb.run(input);
}

3. 根本的な保護策:OSレベルの分離

Node.jsのライブラリだけに頼らず、コンテナやマイクロVMによる隔離を併用します。

# Dockerを使用した隔離実行の例(非特権ユーザーでの実行)

docker run --rm -v $(pwd)/script.js:/app/script.js:ro --net=none --memory="128m" node:slim node /app/script.js

【検出と緩和策】

検出ポイント (EDR/SIEM)

  • 不審な子プロセス生成: サンドボックス実行プロセス(node等)から sh, bash, cmd.exe が起動されていないか。

  • ファイルシステムへの異常アクセス: /etc/passwd や環境変数ファイルへのアクセス試行。

  • プロトタイプ汚染のシグネチャ: HTTPリクエストボディに含まれる __proto__constructor などの文字列をWAFで検知。

緊急緩和策 (Workaround)

  1. ライブラリのアップデート: 最優先事項。npm update sandboxjs を実施。

  2. 外部通信の遮断: サンドボックスを実行するサーバーのアウトバウンド通信をFirewallで厳格に制限。

  3. 代替ライブラリへの検討: isolated-vm のような、V8レベルでメモリを分離する、より堅牢なライブラリへの移行を検討(ただし移行コストに注意)。

【実務上の落とし穴】

  • 可用性への影響: forbiddenTokens などの制限を厳しくしすぎると、正当なスクリプトが動作しなくなる(False Positive)リスクがあります。

  • パフォーマンス劣化: コンテナ化やマイクロVM(Firecracker等)による隔離は、起動オーバーヘッドを伴うため、リアルタイム性が求められる用途では課題となります。

  • 推移的依存関係: 自身のプロジェクトで直接 SandboxJS を使っていなくても、依存している他のライブラリ(SDK等)が内部で使用しているケースを見落としがちです。npm list sandboxjs で確認してください。

【まとめ】

組織のCSIRTおよび開発チームは、以下の3点を即座に実施してください。

  1. インベントリ確認: 全プロジェクトにおいて SandboxJS の使用の有無とバージョンを確認する。

  2. パッチ適用: 脆弱性が修正された最新バージョンへ強制アップデートを行う。

  3. 多層防御の導入: ライブラリの修正だけに頼らず、コンテナ隔離やネットワーク制限(Egressフィルタリング)を適用し、万が一の脱出に備える。


参考文献:

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

コメント

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