import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("security")

# セキュリティ

agent-browser には、資格情報の漏洩、信頼できないページコンテンツによるプロンプトインジェクション、および不正なブラウザ操作を防ぐためのセキュリティ機能が含まれています。

すべてのセキュリティ機能はオプトインです。デフォルトでは、agent-browser はナビゲーション、操作、出力に制限を設けません。ご自身の展開に応じて必要な機能のみを有効化してください。明示的に機能を有効化しない限り、既存のワークフローは影響を受けません。

## 脅威モデル

これらの機能は、大規模言語モデル(LLM)ベースのエージェントがブラウザを操作する状況において、以下の脅威を緩和することを目的としています。

- **資格情報の漏洩** — 認証バンクに保存されたパスワードは、常に LLM のコンテキストに含まれません。CLI はバンク操作をローカルで処理しており、資格情報はデーモンの IPC チャネルを経由して送信されません。
- **ページコンテンツによるプロンプトインジェクション** — 悪意のあるページは、ツール出力やシステム指示のように見えるテキストを埋め込む可能性があります。コンテンツ境界マーカー(`--content-boundaries`)により、オーケストレータは信頼できるツール出力と信頼できないページコンテンツを区別できます。
- **不正なナビゲーション / データ流出** — 改ざんまたは操られたエージェントが攻撃者所有のドメインにアクセスし、データを流出させる可能性があります。ドメイン許可リスト(`--allowed-domains`)により、許可されていないドメインへのナビゲーション、サブリソース要求、WebSocket 接続、EventSource ストリーム、`sendBeacon` 呼び出しをブロックします。
- **不正な破壊的アクション** — アクションポリシー(`--action-policy`)および確認ゲート(`--confirm-actions`)により、明示的な承認なしに危険な操作(`eval`、ダウンロード、アップロードなど)を実行できなくなります。
- **コンテキストの過負荷** — 大きなページ出力は、LLM のコンテキストウィンドウを圧倒する可能性があります。出力の切り詰め(`--max-output`)により、ページからの出力のサイズに上限を設けています。

### 既知の制限事項

- **WebSocket/EventSource のブロッキングは最善策です。** 初期スクリプトによるブラウザコンストラクタの上書きによって実現されています。ただし、`eval` アクションカテゴリが許可されている場合、ページスクリプトが理論的には元のコンストラクタを復元できる可能性があります。最大の保護を得るには、`--action-policy` を使用して `eval` を拒否してください。
- **リモート接続におけるドメインフィルタのタイミング。** CDP またはクラウドプロバイダ経由で既存のブラウザに接続する場合、ドメインフィルタがインストールされる前にページがすでにコンテンツを読み込んでいる可能性があります。agent-browser はフィルタが有効化された後、許可されていないページを `about:blank` にナビゲートしますが、その時点以前に読み込まれたリソースについては後からブロックすることはできません。
- **コンテンツ境界は多重防御戦略です。** これには、LLM およびオーケストレータが構造的マーカーを尊重することに依存しています。十分に高度な悪意あるページは境界形式を模倣しようとする可能性がありますが、各プロセスに固有の CSPRNG ノンスがあるため、予測は実用的に不可能です。
- **確認のタイムアウト。** 保留中の確認は 60 秒後に自動的に拒否されます。オーケストレータはこの期間内に応答する必要があります。
- **非 TTY 状態での自動拒否。** `--confirm-interactive` が設定されているが標準入力が端末(TTY)でない場合(例:パイプされた入力や自動化パイプライン内)、アクションは自動的に拒否されます。これにより、非インタラクティブな環境での誤った承認を防止します。

## 認証バンク

ローカルに資格情報を保存し、名前で参照します。LLM はパスワードを一切見ることはありません。

```bash
# 資格情報を保存(AGENT_BROWSER_ENCRYPTION_KEY が設定されていれば暗号化)
# 推奨:シェル履歴やプロセス一覧への露出を避けるため、標準入力経由でパスワードを渡す
echo "pass" | agent-browser auth save github --url https://github.com/login --username user --password-stdin

# 直接渡す場合(警告が表示されます)
agent-browser auth save github --url https://github.com/login --username user --password pass

# 保存済みの資格情報を使用してログイン
agent-browser auth login github

# 保存済みのプロファイル一覧表示(名前と URL だけ、シークレットは含まない)
agent-browser auth list

# プロファイルのメタデータ表示
agent-browser auth show github

# プロファイルの削除
agent-browser auth delete github

自動検出に失敗した場合は、カスタムセレクタを指定できます:

agent-browser auth save myapp \
  --url https://app.example.com/login \
  --username user --password pass \
  --username-selector "#email" \
  --password-selector "#password" \
  --submit-selector "button.login"

プロファイルは ~/.agent-browser/auth/ に保存され、常に AES-256-GCM で暗号化されます。AGENT_BROWSER_ENCRYPTION_KEY が設定されていない場合、初回使用時に ~/.agent-browser/.encryption-key に自動生成されたキーが作成されます。移行性のためにこのファイルのバックアップまたは環境変数の明示的設定をお勧めします。

Unix(chmod 600/700)および Windows(icacls で現在のユーザーのみに制限)の両方でファイルパーミッションが強制され、他のユーザーが暗号化キーまたは認証プロファイルを読むことを防ぎます。

コンテンツ境界マーカー

--content-boundaries が有効化されている場合、すべてのページ出力は構造的マーカーでラップされ、LLM がツール出力と信頼できないページコンテンツを識別できるようになります:

--- AGENT_BROWSER_PAGE_CONTENT nonce=a1b2c3d4 origin=https://example.com ---
[snapshot / text / html / eval output here]
--- END_AGENT_BROWSER_PAGE_CONTENT nonce=a1b2c3d4 ---

ノンスは各 CLI プロセスの起動ごとにランダムに生成されるため、境界を偽装しようとするページコンテンツにとって予測不可能です。

フラグまたは環境変数で有効化できます:

agent-browser --content-boundaries snapshot
# または
export AGENT_BROWSER_CONTENT_BOUNDARIES=1

対象となる出力タイプ:snapshot, get text, get html, eval, console

--json モードでは、境界メタデータが _boundary オブジェクトとして JSON 応答に注入され、nonce および origin フィールドを含むため、オーケストレータがプログラム的に発信元を検証できます:

{
  "success": true,
  "data": { "snapshot": "...", "origin": "https://example.com" },
  "_boundary": { "nonce": "a1b2c3d4e5f6...", "origin": "https://example.com" }
}

ドメイン許可リスト

ブラウザが操作できるドメインを制限し、リダイレクト攻撃やデータ流出を防ぎます:

agent-browser --allowed-domains "example.com,*.example.com,github.com" open https://example.com
# または
export AGENT_BROWSER_ALLOWED_DOMAINS="example.com,*.example.com"

正確な一致(github.com)およびワイルドカードプレフィックス(*.example.com、これは単独のドメイン example.com も含む)をサポートします。許可されていないドメインへのページナビゲーションおよびサブリソース要求(スクリプト、画像、fetch、XHR など)はブロックされ、データ流出を防止します。WebSocket および EventSource 接続もコンストラクタレベルのパッチによりブロックされます。HTTP(S) 以外のサブリソース(data URI、blob など)は引き続き許可されます。リクエストがブロックされた場合、コマンドはエラーを返します。

注記: WebSocket/EventSource のブロッキングは最善策です — これは初期スクリプトによるブラウザコンストラクタの上書きによって実現されています。eval アクションカテゴリが許可されている場合、ページスクリプトが理論的には元のコンストラクタを復元できる可能性があります。最大の保護を得るには、--allowed-domains を使用する際、--action-policyeval カテゴリを拒否してください。

構成ファイル:

{
  "allowedDomains": ["example.com", "*.example.com", "github.com"]
}

CDN およびサードパーティリソース: ドメインフィルタは、許可されていないドメインへのすべてのサブリソース要求(スクリプト、スタイルシート、画像、フォント、fetch/XHR など)をブロックします。ほとんどのウェブサイトは CDN ドメインからアセットを読み込みます。これらのドメインを許可リストに含めるか、ページが動作しなくなります。例えば:

--allowed-domains "myapp.com,*.myapp.com,cdn.jsdelivr.net,fonts.googleapis.com,fonts.gstatic.com"

アクションポリシー

静的ポリシーファイルを使ってアクションをガートします。ポリシーはデーモンによって強制され、拒否されたアクションは即時失敗します。

agent-browser --action-policy ./policy.json open https://example.com
# または
export AGENT_BROWSER_ACTION_POLICY=./policy.json

例:許容的なポリシー(特定の拒否あり):

{
  "default": "allow",
  "deny": ["eval", "download", "upload"]
}

例:制限的なポリシー:

{
  "default": "deny",
  "allow": ["navigate", "snapshot", "click", "scroll", "wait", "get"]
}
カテゴリアクション
navigateopen, back, forward, reload, tab new
clickclick, dblclick, tap
fillfill, type, keyboard type/inserttext, select, check, uncheck
evaleval, evalhandle, addscript, addinitscript, addstyle, expose, setcontent
downloaddownload, waitfordownload
uploadupload
snapshotsnapshot, screenshot, pdf, diff
scrollscroll, scrollintoview
waitwait, waitforurl, waitforloadstate, waitforfunction
getget text/html/url/title, count, isvisible, getbyrole, getbytext, getbylabel, etc.
interacthover, focus, drag, press, keydown, keyup, mousemove, dispatch
networknetwork route/unroute, requests
statestate save/load, cookies set, storage set

認証バンク操作(auth save, auth login, auth list, auth show, auth delete)およびその他の内部/メタ操作は、信頼できるローカル操作であるため、アクションポリシーの適用を回避します。ただし、auth login のナビゲーションにはドメイン許可リストの制限が依然適用されます。

アクション確認

明示的な承認が必要なアクションに対しては、--confirm-actions を使って確認が必要なカテゴリを指定します:

# オーケストレータモード:確認が必要な応答を返す
agent-browser --confirm-actions eval,download eval "document.title"

# その後、承認または拒否:
agent-browser confirm c_8f3a1234
agent-browser deny c_8f3a1234

インタラクティブ(人間による確認)モード:

agent-browser --confirm-actions eval,download --confirm-interactive eval "document.title"
# プロンプト:許可しますか? [y/N]

保留中の確認は 60 秒後に自動的に拒否されます。

非 TTY 行動: --confirm-interactive が設定されているが標準入力が TTY でない場合(例:パイプされた入力、または自動化パイプライン内での実行)、アクションは自動的に拒否されます。これにより、非インタラクティブな環境での誤った承認を防止します。

出力長制限

大きなページ出力によるコンテキストの過負荷を防ぐために、出力を切り詰めます:

agent-browser --max-output 50000 get text body
# または
export AGENT_BROWSER_MAX_OUTPUT=50000

対象となる出力タイプ:snapshot, get text, get html, eval, console

環境変数

変数説明
AGENT_BROWSER_CONTENT_BOUNDARIESページ出力を境界マーカーでラップ
AGENT_BROWSER_MAX_OUTPUTページ出力の最大文字数
AGENT_BROWSER_ALLOWED_DOMAINSカンマ区切りの許可ドメインパターン
AGENT_BROWSER_ACTION_POLICYアクションポリシーの JSON ファイルパス
AGENT_BROWSER_CONFIRM_ACTIONS確認が必要なアクションカテゴリ(カンマ区切り)
AGENT_BROWSER_CONFIRM_INTERACTIVEインタラクティブな確認プロンプトを有効化
AGENT_BROWSER_ENCRYPTION_KEYAES-256-GCM 暗号化用の 64 文字のハッシュキー(認証バンク + セッション)

推奨構成

本番環境向け AI エージェント展開用の推奨設定:

{
  "contentBoundaries": true,
  "maxOutput": 50000,
  "allowedDomains": ["your-app.com", "*.your-app.com"],
  "actionPolicy": "./policy.json"
}