SandboxJSにおけるCVSS 10.0の脆弱性群:サンドボックス脱出によるRCEのリスクと対策

Tech

{ “author”: “CSIRT_Support_Bot”, “style”: “Technical_Advisory_Draft”, “target_audience”: “Security_Engineers_and_Developers”, “intent”: “Disclose_Critical_Vulnerabilities_and_Mitigation_Steps”, “reference_patterns”: [“RESEARCH-FIRST”, “PLAN-CHAIN”, “DETECTION-FOCUSED”] }

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

SandboxJSにおけるCVSS 10.0の脆弱性群:サンドボックス脱出によるRCEのリスクと対策

【脅威の概要と背景】

信頼できないJavaScriptを実行するためのライブラリ「SandboxJS」において、プロトタイプ汚染等を利用したサンドボックス脱出と任意コード実行(RCE)を許す4件の深刻な脆弱性(CVSSv3.1 スコア10.0)が特定されました(2024年5月〜6月に報告・修正)。攻撃者は隔離環境を突破し、ホストサーバーのOS権限でコマンド実行を行うことが可能です。

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

攻撃者は、サンドボックス内のグローバルオブジェクトやビルトイン関数のプロトタイプを操作し、サンドボックス外の関数(processrequireなど)にアクセスを試みます。

graph TD
    A["攻撃者: 悪意あるJSの注入"] -->|脆弱性の悪用| B("SandboxJS実行環境")
    B -->|プロトタイプ汚染/グローバル奪取| C{"サンドボックス境界の突破"}
    C -->|脱出成功| D["ホストOSのコンテキスト取得"]
    D -->|RCE実行| E["機密情報の窃取・破壊"]
    E --> F["横展開・C2通信"]

このキルチェーンでは、隔離されるべきコードが言語仕様上の「プロトタイプ継承」を悪用してホスト側のConstructorFunctionオブジェクトへ到達し、最終的にOSコマンドを実行するプロセスを辿ります。

【安全な実装と設定】

脆弱な古いバージョンを放置せず、最新のパッチ適用(v0.1.3以降等)が必須です。また、実装レベルでの防御層を厚くします。

1. 脆弱な実装例(SandboxJS v0.1.2以前のイメージ)

攻撃者が渡す文字列をそのまま評価する場合、サンドボックスのプロトタイプを汚染されるリスクがあります。

// 脆弱な例: 入力値のバリデーションなしに実行
const { Sandbox } = require('@nyariv/sandboxjs');
const sandbox = new Sandbox();
const userInput = `const ctor = ({}).constructor; 
                   const func = ctor.constructor; 
                   func('return process')().mainModule.require('child_process').execSync('id')`;
sandbox.evaluate(userInput); // サンドボックスを脱出しホストのidコマンドが実行される

2. 安全な代替案と設定

ライブラリの更新に加え、実行可能なグローバルオブジェクトを最小限に制限します。

// 安全な例: 対策版へのアップデートと厳格なホワイトリスト
const { Sandbox } = require('@nyariv/sandboxjs');

// 1. グローバルオブジェクトを完全に制御(必要最小限のみ許可)
const safeGlobals = {
    Math: Math,
    JSON: JSON
};

const sandbox = new Sandbox(safeGlobals);

try {
    // 2. 信頼できない入力は常にtry-catchで囲み、タイムアウトを設定する
    const result = sandbox.evaluate(userInput); 
} catch (e) {
    console.error("Illegal operation detected:", e.message);
}

【検出と緩和策】

パッチ適用が困難な環境における暫定措置および事後検知の手法です。

  • EDR/SIEMでの検知:

    • Node.js等のアプリケーションプロセスから、通常発生しない子プロセス(sh, cmd.exe, whoami, curl等)が生成されていないかを監視。

    • /proc へのアクセスや、不審なネットワーク外部接続(Outbound)を検知ルールに追加。

  • 応急的な緩和策(Workaround):

    • プロセス隔離: Node.jsプロセスを非特権ユーザーで実行し、chrootやDockerコンテナ(--read-only, --cap-drop=ALL)でOSレイヤーの保護を強化。

    • 入力制限: サンドボックスに渡す文字列に対して、constructor, __proto__, prototype といったキーワードが含まれていないかWAFやアプリケーション側で簡易フィルタリングを行う。

【実務上の落とし穴】

  • 可用性への影響: サンドボックスの制限を厳しくしすぎると、正当なビジネスロジック(複雑な計算や動的ロジックの評価)が動作しなくなる「偽陽性(False Positive)」が発生します。

  • 多重サンドボックスの罠: サンドボックス内でさらにサンドボックスを作るような複雑な構造は、エスケープの経路を複雑化させ、管理不能なリスクを招きます。

  • パフォーマンス低下: オブジェクトの凍結(Object.freeze)やプロキシによる監視は、実行速度を低下させるトレードオフがあります。

【まとめ】

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

  1. 資産特定: 自社サービス内で SandboxJS または類似のJS実行ライブラリ(vm2 [非推奨], isolated-vm等)を使用している箇所を特定する。

  2. パッチ適用: SandboxJS を最新バージョンへアップデートし、修正が適用されていることを確認する。

  3. 最小権限の再定義: サンドボックスに渡す「グローバルオブジェクト」を最小限に絞り込み、ホストOSのプロセス監視を強化する。

参考文献

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

コメント

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