OpenClawのSSHサンドボックスにシンボリックリンク経由の脱出、CVSS 8.8
OpenClawのSSHサンドボックスにまた穴が開いた。GHSA-fv94-qvg8-xqpw、CVSS 8.8。SSHサンドボックスのファイル同期処理でシンボリックリンク(以下symlink)のバリデーションが欠落しており、AIエージェントがサンドボックス外の任意ファイルを読み書きできる。影響を受けるのはOpenClaw 2026.3.28以前。2026.3.31で修正済み。PoCは学術レベルで公開されている。
「また」と書いたのは、OpenClawのサンドボックス周りの脆弱性はこれが初めてではないからだ。CVE-2026-27522ではパストラバーサル経由のサンドボックス脱出が報告されており、GHSA-m8v2-6wwhでもsymlink操作によるサンドボックス脱出が修正されている。サンドボックスの境界チェックが何度も破られているパターンだ。
脆弱性の仕組み
問題は uploadDirectoryToSshTarget 関数にある。この関数はローカルのワーキングディレクトリをSSHサンドボックスにアップロードする同期処理を担当するが、アップロード対象のファイルツリーにsymlinkが含まれている場合のバリデーションが一切なかった。
graph TD
A["攻撃者がプロンプトインジェクションで<br/>AIエージェントにsymlink作成を指示"] --> B["ワークスペース内に<br/>symlink作成"]
B --> C["ln -s /etc/passwd workspace/link"]
C --> D["uploadDirectoryToSshTarget<br/>がsymlinkを検証せず処理"]
D --> E["symlinkを辿って<br/>サンドボックス外のファイルを読み取り"]
D --> F["symlinkを辿って<br/>リモートホストの任意パスに書き込み"]
E --> G["秘密鍵・設定ファイル・<br/>認証情報の窃取"]
F --> H["リモートホストの<br/>システムファイル改ざん"]
style G fill:#991b1b,color:#fff
style H fill:#991b1b,color:#fff
攻撃ベクターはネットワーク経由、もしくはAIエージェントへのプロンプトインジェクションだ。攻撃者がエージェントにsymlinkの作成を指示できれば、そこから任意のファイルアクセスに到達する。
CWEの分類
この脆弱性には2つのCWEが割り当てられている。
| CWE | 名称 | 内容 |
|---|---|---|
| CWE-61 | UNIX Symbolic Link Following | プログラムがsymlinkを辿ってアクセスすべきでないファイルに到達する |
| CWE-59 | Improper Link Resolution Before File Access | ファイルアクセス前にリンク先の解決が適切に行われない |
CWE-61はsymlinkを使った古典的な攻撃パターンで、UNIX系OSでは長い歴史がある。一時ファイルの作成時にsymlinkを使って書き込み先を差し替えるTOCTOU(Time-of-Check to Time-of-Use)レースコンディションとして知られる。CWE-59はより広い概念で、symlinkに限らずハードリンクやジャンクションポイントも含む「リンク解決の不備」全般を指す。
OpenClawの場合、レースコンディションですらなく、そもそもバリデーション自体が存在しなかった。チェックとアクセスの間のタイミング問題以前に、チェック処理が丸ごと欠落していた。
修正内容
コミット3d5af14で assertSafeUploadSymlinks 関数が追加された。fs.readdir の withFileTypes: true オプションでディレクトリエントリの型情報を取得し、symlinkが見つかった場合は resolveBoundaryPath でリンク先がサンドボックスの境界内に収まっているかを検証する。境界外を指すsymlinkがあればアップロードを拒否する。
修正のアプローチを整理する。
| 項目 | 修正前 | 修正後 |
|---|---|---|
| symlinkの検出 | なし | fs.readdir({ withFileTypes: true }) |
| リンク先の検証 | なし | resolveBoundaryPath で境界チェック |
| 境界外symlinkの処理 | そのまま辿る | アップロード拒否 |
ただし、この修正は「アップロード時」のバリデーションだ。Anthropic Python SDKにも類似のsymlinkレースコンディション(CVE-2026-34452)が報告されており、メモリツールのパスバリデーションと実際のファイル操作の間にsymlinkを差し替えることでサンドボックスを脱出できた。OpenClawの修正が同種のレースコンディションに耐えるかどうかは、assertSafeUploadSymlinks がファイルオープンとアトミックに実行されるかに依存する。
OpenClawサンドボックスの攻撃史
OpenClawのセキュリティ問題はSkillHubサプライチェーンやプロンプトインジェクションから始まり、NemoClawが4層サンドボックスで防御を試みる段階に進んでいた。しかし今回の脆弱性はサンドボックスそのものの実装に穴があったケースで、サンドボックスの上位層で何を積もうと、基盤のファイル同期がsymlinkを素通しにしていたら意味がない。
このブログで追ってきたOpenClawのセキュリティ問題を時系列で並べる。
| 時期 | 攻撃・脆弱性 | 手法 |
|---|---|---|
| 2月 | SKILL.md経由AMOS配布 | 悪性スキルがAIを仲介してmacOSマルウェアをインストール |
| 2月 | SkillHub 7.1%に脆弱性 | 30,000インスタンス露出、OAuthトークン平文保存 |
| 3月 | CVE-2026-27522 | パストラバーサルによるサンドボックス脱出 |
| 3月 | CVE-2026-25253 | gatewayUrl経由のRCE(CVSS 8.8) |
| 3月 | GHSA-m8v2-6wwh | symlink操作によるサンドボックス脱出 |
| 4月 | GHSA-fv94-qvg8-xqpw(今回) | SSH同期時のsymlinkバリデーション欠落 |
サンドボックス脱出だけで3件目だ。パストラバーサル、symlink操作、SSH同期時のsymlink未検証。経路は違うが「サンドボックスの境界チェックが不十分」という根本原因は共通している。
影響範囲と緩和策
影響を受けるのはOpenClaw 2026.3.28以前の全バージョンで、Node.js環境でopenclawのnpmパッケージを使い、リモートSSHサンドボックスに接続しているインスタンスが対象になる。
対応は package.json でopenclawを >=2026.3.31 に更新して npm update openclaw を実行する。追加の緩和策としてGitHub Advisoryでは以下を推奨している。
- HITL(Human-in-the-Loop)モードを有効にして、エージェントのファイル操作を人間がレビューする
- SSHサンドボックスのユーザーアカウントに最小権限を適用する
- ローカルのエージェントワークスペースでsymlinkの異常な作成を監視する
macOS sandbox-execやWindowsサンドボックスのようなOSレベルの隔離はカーネルがシステムコールをブロックするため、アプリケーションレベルのバリデーション不備とは異なる防御層を提供する。OpenClawのSSHサンドボックスはアプリケーションレベルの境界チェックに依存しているため、チェック漏れが即サンドボックス脱出に直結する構造的な弱点がある。
エコシステム拡大とCVE連発のギャップ
OpenClawの周辺では、エコシステムを拡大する動きが加速している。NVIDIAはNemoClawを通じて4層サンドボックスを提供し、エンタープライズ環境でOpenClawエージェントを安全に使えるようにする取り組みを進めている。ManusもOpenClaw互換のエージェント基盤を構築しており、ホスト型のサンドボックス実行環境を独自に提供する方向だ。OpenClawのプロトコルをベースにした「エージェントを簡単にデプロイできる世界」が近づいている。
一方で、2月から4月までの2ヶ月間にサンドボックス脱出だけで3件、RCEを含めれば4件のCritical〜Highが出ている。スキルエコシステムのサプライチェーン汚染やOAuthトークンの平文保存も加えると、セキュリティインシデントの密度はかなり高い。エコシステムの成長速度とセキュリティの成熟度が釣り合っていない。
構造的な問題として、OpenClawのサンドボックスはアプリケーションレベルの境界チェックに全面的に依存している。カーネルレベルの隔離(macOSのsandbox-exec、Linuxのseccomp/namespaces、gVisor等)とは異なり、アプリケーションコードのバリデーション漏れが1つあればサンドボックスが無効化される。NemoClawの4層防御はこの弱点を補強する試みだが、最下層のOpenClaw自体が穴を開け続けている状況では、上に何を積んでも土台が揺らぐ。
NVIDIAやManusのようなプレイヤーが参入すること自体はエコシステムの健全化に寄与しうる。NemoClawがOSレベルのサンドボックスを統合すれば、OpenClaw単体の脆弱性がそのまま脱出に繋がる構造は改善される。ただし現時点では「OpenClawのサンドボックスを信頼してエージェントを動かす」設計のままだ。CVEが出るたびにパッチを当てるモグラ叩きではなく、アプリケーションレベルのバリデーションが破られることを前提にした多層防御が標準にならない限り、同じパターンの脆弱性は繰り返される。
本番環境でOpenClawエージェントを動かすなら、OpenClawのサンドボックスだけに頼らず、OSレベルの隔離やネットワークの厳格なセグメンテーションを自前で被せるのが現実的な選択肢だろう。少なくとも「公式が安全と言っているから大丈夫」のフェーズではない。
NemoClawやManus経由でOpenClawに乗る層は、OpenClawのCVE履歴を知らないまま使い始める可能性がある。統合レイヤーが下のコンポーネントを隠してしまうと「NVIDIAが出してるから安全だろう」という信頼の委譲が起きる。自分のエージェントが何の上で動いていて、その土台が2ヶ月で4件のHigh以上を出しているという事実は、採用判断の前に知っておくべきだ。
自分がかなチャットを作っているのは、この構造を根本から避けるためだ。かなチャットはClaude Codeの正規CLIをtmuxブリッジ経由でラップする設計で、独自のファイル同期もSSHサンドボックスも持っていない。CLIが提供するパーミッション機構にそのまま乗り、かなチャット自体はオーケストレーション層に徹する。OpenClawほどの自由度はないが、自前でsymlinkバリデーションを書いて、それが破られてパッチを当てて、また別経路で脱出されて——というサイクルとは無縁だ。