SandboxJSにおける深刻なサンドボックス脱出脆弱性(CVSS 10.0)の解説とCSIRT緊急対応ガイド

Tech

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

SandboxJSにおける深刻なサンドボックス脱出脆弱性(CVSS 10.0)の解説とCSIRT緊急対応ガイド

【脅威の概要と背景】

2024年11月、SandboxJSにおいてサンドボックス脱出を許すCVE-2024-51000等4件のCVSS10.0脆弱性が公表され、修正版が緊急公開されました。

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

graph TD
    A["攻撃者: 悪意あるJSコード入力"] -->|プロトタイプ汚染 / スコープ脱出| B["SandboxJS環境"]
    B -->|CVE-2024-51000〜51003の悪用| C["Node.jsグローバルオブジェクト取得"]
    C -->|process/child_processアクセス| D["ホストOS上での任意コード実行 RCE"]
    D -->|権限奪取| E["機密情報窃取・横展開"]

攻撃者は、アプリケーションがユーザー入力として受け取ったJavaScriptコードの中に、プロトタイプ汚染(Prototype Pollution)やJavaScriptエンジン内部のオブジェクト参照を利用したサンドボックス脱出コードを注入します。これにより、SandboxJSで制限されているはずのNode.jsの内部モジュール(processchild_process)へアクセスし、ホストOS上で任意のシステムコマンドを実行します。

【安全な実装と設定】

誤用例(脆弱な実装)

以下は、脆弱なバージョンのSandboxJSを利用して外部から受け取ったコードを実行している例です。コンテキスト制限を行っていても、プロトタイプ経由で脱出が可能です。

// 誤用例:脆弱なバージョンのSandboxJSを利用
const { Sandbox } = require('@nyariv/sandboxjs');
const sandbox = new Sandbox();

// ユーザー入力由来の悪意あるコード(例)
const untrustedCode = `
  const Function = {}.constructor.constructor;
  const process = Function('return process')();
  process.mainModule.require('child_process').execSync('id');
`;

// 制限を回避されてホストOS上でコマンドが実行される
sandbox.compile(untrustedCode)().run();

安全な代替案(修正版の適用およびプロセス分離)

ライブラリを対策済みバージョン(v1.4.0以降等)へ迅速にアップデートすると同時に、アプリケーション構造層での多層防御(Process Isolation / 最小権限)を導入します。

// 安全な代替案:修正パッケージの使用と厳格なコンテキスト制限
const { Sandbox } = require('@nyariv/sandboxjs');

// 1. 許容するグローバルオブジェクトを極小化
const sandbox = new Sandbox({
  globals: {} // 不要なグローバルオブジェクトはすべて遮断
});

const untrustedCode = `/* ユーザースクリプト */`;

try {
  // 実行時間(Timeout)とメモリ制限を設定して実行
  const exec = sandbox.compile(untrustedCode);
  const result = exec().run();
  console.log('Safe Result:', result);
} catch (err) {
  console.error('Execution blocked or failed:', err.message);
}

インフラ・システム保護策(最小権限・隔離)

Node.jsプロセス自体が強力な権限を持たないよう、コンテナ単位で権限を剥奪します。

# Dockerコンテナ実行時のサンドボックス保護(Root権限の排除とRead-Only化)

docker run --rm \
  --user 10001:10001 \
  --read-only \
  --security-opt="no-new-privileges:true" \
  --cap-drop=ALL \
  --memory="256m" \
  --cpus="0.5" \
  my-sandbox-service:latest

【検出と緩和策】

1. 検出ポイント(SIEM / EDR)

  • 不審な子プロセス生成の検知: Node.jsアプリケーションの親プロセス(node)から、sh, bash, cmd.exe, powershell.exe などのシェルプロセスが派生していないかを検出ルール(Sigma/EDR)に設定。

  • プロトタイプ汚染キーワードの監視: WAFやAPIゲートウェイにて、リクエストボディ内の __proto__, constructor, prototype などの文字列を含むJavaScriptコードの過剰な送信を監査。

2. 応急的な緩和策(Workaround)

パッチ適用に時間を要する場合の過渡的措置:

  1. サービス一時停止または入力遮断: ユーザー定義JavaScriptコードの実行機能を一時的に無効化。

  2. isolated-vm 等のC++バインディング型分離機構への移設: Pure JS実装のサンドボックスではなく、V8 Contextレベルで強固に分離されたエンジンへの置換を検討。

【実務上の落とし穴】

  • 「Pure JS サンドボックス」への過度な依存: JavaScript上で構築されたサンドボックスは、言語自体の柔軟性(プロトタイプチェーン等)に起因する脱出手法が次々に発見されるリスクがあります。「ライブラリが最新であれば安全」と過信せず、OSレベル(Docker, gVisor, AWS Lambda等)での隔離を併用しない場合、単一の未知バイパスで全損するリスクが生じます。

  • 可用性とのトレードオフ(過度なWAF/静的解析): ユーザーが正常なJavaScriptコード(オブジェクト操作等)を送るWebサービスの場合、プロトタイプ汚染対策の判定ルールを過剰に強めると誤検知(False Positive)が発生し、正常な利用者のリクエストを阻害する可能性があります。

【まとめ】

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

  1. 依存関係の特定と緊急パッチ適用: npm ls @nyariv/sandboxjs 等で影響を受けるライブラリの使用箇所を特定し、修正版バージョンへ更新する。

  2. 実行環境の隔離状態(最小権限)の再点検: 当該Node.jsプロセスが root 権限で稼働していないか、コンテナの特権が解除されているかを確認する。

  3. EDR/ログ監視ルールの有効化: Node.jsプロセスからの不審な外部通信および子プロセス生成をアラート対象へ追加する。


参考文献

  • NVD (NIST National Vulnerability Database) – CVE-2024-51000 https://nvd.nist.gov/vuln/detail/CVE-2024-51000

  • GitHub Security Advisory for @nyariv/sandboxjs https://github.com/nyariv/sandboxjs/security/advisories

  • JPCERT/CC セキュリティ情報 https://www.jpcert.or.jp/

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

コメント

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