年末から新年にかけて、OpenClawのClawHubプラグインマーケットで大規模な供給チェーン汚染が発生し、340を超える悪意のあるスキルが混入しました。攻撃者はSKILL.mdファイル内の偽装された「インストール手順」を通じて、ユーザーがターミナルで悪意のあるコマンドを実行するよう誘導し、SSH秘密鍵やAPIキー、暗号通貨ウォレットなどの機密情報を盗み出しました。
この出来事は、私たちに重要な問いを提起しました:AIエージェントがサードパーティコードを実行する必要がある場合、各種サンドボックス対策は現実的な攻撃シナリオに対してどの程度の防御能力を持つのか?
私たちは4つのオープンソースサンドボックスソリューションを対象に20項目のセキュリティテストを実施し、ClawHavocで観測された攻撃手法をカバーするテストケースを使用しました。本稿ではテストデータと当社のSkillLiteにおける工学的考察を共有します。
ClawHavocが示した教訓
ClawHavocの攻撃チェーンは以下の通りです:悪意のあるスキル → os.system("curl ... | bash")またはユーザー誘導による実行 → 攻撃者サーバーからの第2段階ペイロード取得 → SSH秘密鍵、環境変数、キーチェーンなどの機密情報読み取り。
この攻撃チェーンを分解すると、サンドボックスセキュリティのコア要素が明らかになります:プロセス実行制御(os.systemの阻止)、ネットワーク分離(curl外部接続の阻止)、ファイルシステム分離(SSH秘密鍵読み取りの阻止)、情報漏洩防止(環境変数読み取りの阻止)。
テスト設計と結果
ファイルシステム、ネットワーク、プロセス、リソース制限、コード注入、情報漏洩の20項目の攻撃シナリオをカバーし、「ブロック」「部分ブロック」「許可」を記録しました。
| ソリューション | ブロック数 | スコア | 概要 |
|---|---|---|---|
| SkillLite (レベル3) | 18/20 | 90.0% | Rustネイティブサンドボックス + 静的スキャン |
| Pyodide | 7/20 | 35.0% | WebAssemblyサンドボックス(LangChain採用) |
| Claude SRT | 6.5/20 | 32.5% | Anthropicオープンソースサンドボックス |
| Docker | 2/20 | 10.0% | コンテナ分離 |
詳細比較
| テスト項目 | SkillLite (L3) | Docker | Pyodide | Claude SRT |
|---|---|---|---|---|
| ファイルシステム | ||||
| /etc/passwd読み取り | ||||
| SSH秘密鍵読み取り | ||||
| /tmp書き込み | ||||
| ディレクトリトラバーサル | ||||
| ルートディレクトリ列挙 | ||||
| ネットワーク | ||||
| HTTPリクエスト | ||||
| DNSクエリ | ||||
| ポートリッスン | ||||
| プロセス | ||||
| os.system() | ||||
| subprocess | ||||
| プロセス列挙 | ||||
| シグナル送信 | ️ | |||
| リソース制限 | ||||
| メモリ爆弾 | ||||
| Fork爆弾 | ||||
| CPU爆弾 | ||||
| コード注入 | ||||
| 動的import os | ||||
| eval/exec | ||||
| 組み込み関数変更 | ||||
| 情報漏洩 | ||||
| 環境変数読み取り | ||||
| システム情報取得 |
ClawHavoc攻撃チェーンを考慮すると、悪意のあるスキルがmain.py内でos.system("curl ... | bash")を試みる場合(表の"os.system()"と"HTTPリクエスト"に対応)、さらに~/.ssh/id_rsa("SSH秘密鍵読み取り"に対応)と環境変数("環境変数読み取り"に対応)を読み取ろうとする際、SkillLiteはこれらすべてをブロックしますが、他の多くのソリューションは少なくとも2つの環境内で許可しています。
異なる設計目標が結果を分ける
Dockerはテストで低いブロック率を示しましたが、これはDockerが「安全ではない」という意味ではありません。その設計目標はアプリケーションデプロイ分離であり、悪意のあるコード実行に対する防御ではありません—これは異なる問題領域です。
伝統的デプロイ vs AIエージェントスキルの比較:
| 伝統的デプロイ | AIエージェントスキル |
|---|---|
| 信頼できる開発チームのコード | 信頼できないサードパーティのコード |
| リソース分離が目的 | 悪意のある行動の防御が目的 |
| コンテナ内ネットワーク/ファイルアクセスが必要機能 | コンテナ内ネットワーク/ファイルアクセスが攻撃経路になる可能性 |
全連鎖防御のアプローチ
SkillLiteが20項目中18項目をブロックできるのは、単一層の強さではなく、インストール前、実行前、実行中の3段階で防御を試みているためです。
3層防衛アーキテクチャ
┌─────────────────────────────────────────────────┐
│ 第1層:インストール時スキャン │
│ ├─ 静的ルールスキャン(regexによる悪意パターン検出)│
│ ├─ LLM知的分析(疑わしいコードを大規模モデルで再判定)│
│ └─ サプライチェーン監査(PyPI/OSV脆弱性DB照合) │
├─────────────────────────────────────────────────┤
│ 第2層:実行前承認 │
│ ├─ 2段階確認(スキャン → ユーザー確認 → 実行) │
│ └─ スキャンIDバインド(スキャンバイパス実行防止) │
├─────────────────────────────────────────────────┤
│ 第3層:ランタイムサンドボックス │
│ ├─ OSネイティブ分離(macOS Seatbelt / Linux bwrap)│
│ ├─ プロセス実行ホワイトリスト(インタープリターのみ許可)│
│ ├─ ファイルシステム分離(センシティブパスdeny + モバイル保護)│
│ ├─ ネットワーク分離(Seatbelt deny + プロキシフィルタ)│
│ ├─ リソース制限(rlimit CPU/メモリ/ファイル/プロセス数)│
│ └─ IPCブロック(deny mach-register/iokit-open) │
└─────────────────────────────────────────────────┘
実装での経験則
ブラックリストからホワイトリストへ
初期には危険コマンド(/bin/sh、/usr/bin/curlなど)をブラックリストでブロックしていましたが、攻撃者がパス変形(/usr/local/bin/bash、シンボリックリンク)で回避できることを発見しました。
現在は厳格なホワイトリスト方式:Seatbeltのprocess-execはインタープリターへのパスのみを許可します。
;; インタープリター実行のみ許可
(allow process-exec (literal "/path/to/python3"))
(allow process-exec (literal "/path/to/canonical/python3"))
;; macOS Python.framework互換性
(allow process-exec (subpath "/path/to/Python.framework/Versions/3.x"))
;; その他のプロセス実行を拒否
(deny process-exec)
サンドボックス失敗時のフォールバック禁止
初期の誤りとして、サンドボックス起動失敗時に無サンドボックス実行に戻すという設計がありました。これは攻撃者にとって回避経路を提供することになります。
現在の戦略:サンドボックス失敗 → エラー終了、決してフォールバックしない
match secure_execution_handler(skill_directory, runtime_env, config_params, input_data, resource_limits) {
Ok(execution_result) => Ok(execution_result),
Err(error_occurred) => {
Err(error_occurred.context(
"Security sandbox initialization failed. Execution will not proceed \
without proper isolation mechanisms active."
))
}
}
各ソリューションのセキュリティカバレッジ
| セキュリティ能力 | SkillLite | Docker | Pyodide | SRT |
|---|---|---|---|---|
| インストール時有害コード検出 | ✓ | — | — | — |
| 静的コード解析 | ✓ | — | — | — |
| サプライチェーン監査 | ✓ | — | — | — |
| プロセス実行ホワイトリスト | ✓ | — | — | — |
| IPC/カーネル操作ブロック | ✓ | — | — | — |
| ファイルシステム分離 | ✓ | 一部 | ✓ | 一部 |
| ネットワーク分離 | ✓ | — | ✓ | ✓ |
| リソース制限 | ✓ | 一部 | 一部 | 一部 |
セキュリティとパフォーマンスのバランス
通常、セキュリティとパフォーマンスは相反する関係ですが、セキュリティ機構がOSカーネル機能であればオーバーヘッドを最小限に抑えることができます。
| 次元 | SkillLite | Docker | Pyodide | SRT |
|---|---|---|---|---|
| ホット起動 | 40ms | 194ms | 672ms | 596ms |
| コールド起動 | 492ms | 120s | ~5s | ~1s |
| メモリ使用量 | ~10MB | ~100MB | ~50MB | 84MB |
| バイナリサイズ | ~2MB | 200MB+デーモン | 50MB+WASM | インストール必要 |
エコシステム全体の現状
AIエージェントフレームワークのセキュリティ分離はまだ初期段階にあります:
| ソリューション | サンドボックス方式 | インストール時スキャン | コード監査 | サプライチェーン保護 |
|---|---|---|---|---|
| SkillLite | Seatbelt/bwrapネイティブサンドボックス | ✓ | ✓ | ✓ |
| Open Interpreter | サンドボックスなし | — | — | — |
| AutoGPT / CrewAI | Dockerまたはなし | — | — | — |
| LangChain | Pyodideまたはなし | — | — | — |
| E2B | クラウドmicroVM | — | — | — |
| Claude SRT | Seatbelt | — | — | — |
改善点の認識
SkillLiteにも以下の明確な課題があります:
| 課題 | 説明 | 対応計画 |
|---|---|---|
| メモリ爆弾未ブロック | RLIMIT_ASデフォルト値が高すぎる |
256MBに制限、フォールバックパス追加 |
| 組み込み関数変更未ブロック | regexパターンがすべてのケースをカバーしていない | ルール強化 + ASTスキャン |
| Linux seccomp不完全 | AF_UNIXのみブロック | ptrace/mount/clone等拡張 |
| 署名検証が文字列比較 | 暗号論的検証ではない | Ed25519導入 |
(allow default)使用中 |
macOS Seatbelt完全deny未実装 | 段階的移行中 |
| 静的スキャンが回避されやすい | 純粋なregexは難読化回避不可 | tree-sitter AST分析検討 |
テスト再現方法
すべてのテストスクリプトとデータはオープンソースです:
git clone https://github.com/EXboys/skilllite
cd skilllite
# ビルド
cargo build --release
# セキュリティ比較テスト実行
python3 benchmark/security_vs.py
# パフォーマンス比較テスト実行
python3 benchmark/benchmark_runner.py --compare-levels -n 100 -c 10