Safari MCP上に構築された自動化ツールが、開発者のダッシュボードタブを読み取っている最中に閉じてしまった。この事象は、AI駆動のエージェントが自身に属さないタブに触れないようにするためのガード(保護機能)に潜んでいた隠れた欠陥を露呈させ、「デフォルトで安全(safe-by-default)」なカテゴリ分けがいかにリスクになり得るかを示している。

機能していたガード —— ある時までは

このツールは、自身が作成したすべてのタブに内部識別子をタグ付けする。エージェントがコマンドを発行する前に、ガードはそのマーカーを確認する。マーカーが見当たらない場合、ガードは動作を拒否する。実際、このガードはエージェントが自身で開いていないページを読み取るのを阻止しており、まさに設計通りの動作をしていた。

しかし、フォーム入力中にページが別のドメインにリダイレクトされた。このリダイレクトによってマーカーが剥がれ落ち、タブにラベルが付かない状態になった。ガードはマーカーの欠如を検知し、「所有権を確認できないため、このタブは読み取りません」と報告した。その時点では、セーフティチェックは意図通りに動作していた。

一線を越えてしまったクリーンアップコード

次に、マーカーのない「孤立したタブ」を閉じるための手動クリーンアップルーチンが実行された。このルーチンは、まず所有権を確認することなく、ツールに対して「タブを閉じる」よう要求した。ガードは、そのタブが自身の所有物であることを証明できなかったため、ツールはデフォルトのアクションである「現在のタブを閉じる」へとフォールバックした。この「現在のタブ」とは、開発者が読んでいたダッシュボードであり、孤立したタブではなかった。

その結果、本来なら行き止まりであるべきセーフティパスによって、破壊的な操作が引き起こされてしまった。

「所有権なし」を「許可」とみなしてしまった3つのレイヤー

  1. コマンドのカテゴリ分け – コマンドをグループ化するリストにおいて、close_tab が「タブ管理」という広範なバケットに分類されていた。開発者は、他のコマンド(list tabs など)が情報の読み取りのみを行うため、そのバケット内のものはすべて無害であると思い込んでいた。close_tab が破壊的であることを示す明示的な注記がなかったため、隣接するコマンドと同じ「安全である」という認識を引き継いでしまった。
  2. 拡張機能レベルのポリシー – すべてのブラウザ操作を仲介するSafari拡張機能が、セッションが何も所有していない場合にはあらゆる操作を許可していた。このルールは読み取り専用のアクションには機能するが、同時に close_tab が出所確認なしに実行される道を開いてしまった。
  3. ロジックの不一致 – クリーンアップルーチンは1つのタブの所有権フラグを確認したが、その後、ブラウザが「現在のタブ」として報告したタブに対してクローズ関数を呼び出した。この不一致により、ガードがマーカーを見つけられなかったという失敗が、クローズコマンドをバイパスさせ、誤った対象へとリダイレクトさせてしまった。

各レイヤーが「所有権が記録されていない」ことを「動作しても安全である」と解釈した結果、正当性の証明がないままタブを閉じるコマンドが実行されるに至った。

修正策:破壊的な操作には所有権の証明が必須

修正後のロジックでは、読み取り専用のパスと破壊的なパスを分離している。現在では、close_tab コマンドを実行する前に、ツールは対象のタブに対して有効なマーカーを提示しなければならない。マーカーがない場合、コマンドは現在のタブをデフォルトとして扱うのではなく、エラーをスローする。ガードが汎用的な「何かを実行する」という分岐にフォールバックすることはない。

この変更により、マーカーの欠如が「何もする必要がない」とも「そのまま実行してよい」とも解釈され得る曖昧な状態が解消された。明示的な失敗を強制することで、ツールはユーザーの作業が誤って失われることから保護される。

開発者が注意すべき点

  • カテゴリ名によって安全性を判断しない – 「タブ管理」のようなラベルは、その中の各コマンドが与える影響については何も語っていない。各操作のコスト(読み取りか、破壊か)をコマンド自体に併記すべきである。
  • ガードの条件はアクションの深刻度と一致させる必要がある – 読み取りリクエストに対して十分なチェックであっても、データを削除できるコマンドに対しては不十分である。影響のクラスごとに、個別のバリデーションパイプラインを構築すること。
  • 暗黙的なフォールバックを避ける – ガードが所有権を確認できない場合、最も安全なレスポンスは「中止」であり、デフォルトの対象を選択することではない。デフォルトのアクションは、権限昇格バグの一般的な原因となる。
  • 隣接性の仮定を監査する – コマンドが隣り合って配置されているリストやメニューをレビューすること。コードが明示的に安全性を再評価しない限り、無害なコマンドが隣接するコマンドに寄せられた信頼を継承してしまう可能性がある。

まとめ

所有権のガードが欠落しているのはバグではなく、設計上の欠陥である。すべての破壊的なコマンドを、明示的な権限の証明を必要とする個別のセキュリティドメインとして扱い、「マーカーなし」を「実行してよい」と解釈させてはならない。そうして初めて、自動化ツールは管理対象であるはずのタブそのものを保護することができるようになる。