
sandbox-runtime v0.0.71
コンテナを必要とせず、OSレベルで任意のプロセスに対してファイルシステムとネットワークの制限を強制する軽量なサンドボックスツール。
Anthropic Sandbox Runtime (srt)
コンテナを必要とせず、OSレベルで任意のプロセスに対するファイルシステムおよびネットワークの制限を適用するための軽量なサンドボックスツールです。
srt は、ネイティブのOSサンドボックスプリミティブ(macOS では sandbox-exec、Linux では bubblewrap)とプロキシベースのネットワークフィルタリングを使用します。エージェント、ローカルMCPサーバー、bashコマンド、任意のプロセスの動作をサンドボックス化するために使用できます。
ベータ研究プレビュー
サンドボックスランタイムは、より安全なAIエージェントを実現するために Claude Code 向けに開発された研究プレビューです。より広範なエコシステムがより安全なエージェントシステムを構築できるよう、初期のオープンソースプレビューとして公開されています。初期の研究プレビューであるため、APIや構成形式は変更される可能性があります。AIエージェントをデフォルトでより安全にするためのフィードバックや貢献を歓迎します!
インストール```bash
npm install -g @anthropic-ai/sandbox-runtime
## 基本的な使い方```bash
# Network restrictions
$ srt "curl anthropic.com"
Running: curl anthropic.com
<html>...</html> # Request succeeds
$ srt "curl example.com"
Running: curl example.com
Connection blocked by network allowlist # Request blocked
# Filesystem restrictions
$ srt "cat README.md"
Running: cat README.md
# Anthropic Sandb... # Current directory access allowed
$ srt "cat ~/.ssh/id_rsa"
Running: cat ~/.ssh/id_rsa
cat: /Users/ollie/.ssh/id_rsa: Operation not permitted # Specific file blocked
概要
このパッケージは、CLIツールとライブラリの両方として使用できるスタンドアロンのサンドボックス実装を提供します。一般的な開発者のユースケースに合わせたセキュア・バイ・デフォルトの設計思想に基づいており、プロセスは最小限のアクセス権で起動し、必要な穴だけを明示的に開けることができます。
主な機能:
- ネットワーク制限: HTTP/HTTPSおよびその他のプロトコルを介してアクセスできるホスト/ドメインを制御
- ファイルシステム制限: 読み書きできるファイル/ディレクトリを制御
- Unixソケット制限: ローカルIPCソケットへのアクセスを制御
- 違反監視: macOSでは、システムのサンドボックス違反ログストアを利用してリアルタイムアラートを受信
ユースケース例: MCPサーバーのサンドボックス化
重要なユースケースとして、Model Context Protocol (MCP) サーバーをサンドボックス化してその機能を制限する方法があります。例えば、filesystem MCPサーバーをサンドボックス化する場合:
サンドボックスなし (.mcp.json):```json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem"]
}
}
}
**サンドボックスあり** (`.mcp.json`):```json
{
"mcpServers": {
"filesystem": {
"command": "srt",
"args": ["npx", "-y", "@modelcontextprotocol/server-filesystem"]
}
}
}
次に、~/.srt-settings.json で制限を設定します:```json
{
"filesystem": {
"denyRead": [],
"allowWrite": ["."],
"denyWrite": ["~/sensitive-folder"]
},
"network": {
"allowedDomains": [],
"deniedDomains": []
}
}
これで、MCPサーバーは拒否されたパスへの書き込みがブロックされます:```
> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/ollie/sensitive-folder/test.txt'
仕組み
サンドボックスは、プロセスツリー全体に適用される制限を強制するために、OSレベルのプリミティブを使用します:
- macOS:
sandbox-execと動的に生成された Seatbelt プロファイル を使用します - Linux: ネットワーク名前空間の分離を伴うコンテナ化に bubblewrap を使用します
- Windows: 専用の
srt-sandboxローカルユーザーアカウントでサンドボックス化されたプロセスを実行し、そのアカウントの SID をキーとする Windows Filtering Platform 送信フェンスと、作業ツリーに対するセッションごとの明示的な ACE を使用します
0d1c612947c798aef48e6ab4beb7e8544da9d41a-4096x2305
二重分離モデル
効果的なサンドボックス化には、ファイルシステムとネットワークの両方の分離が必要です。ファイル分離がないと、侵害されたプロセスが SSH キーやその他の機密ファイルを外部に持ち出す可能性があります。ネットワーク分離がないと、プロセスがサンドボックスから脱出して、無制限のネットワークアクセスを取得する可能性があります。
ファイルシステム分離は、読み取りと書き込みの制限を強制します:
- 読み取り (deny-then-allow パターン): デフォルトでは、読み取りアクセスはどこでも許可されています。広い領域 (例:
/Users) を拒否し、その中の特定のパス (例:.) を再度許可することができます。allowReadはdenyReadよりも優先されます — これは書き込みの逆で、denyWriteはallowWriteよりも優先されます。 - 書き込み (allow-only パターン): デフォルトでは、書き込みアクセスはどこでも拒否されています。パス (例:
.、/tmp) を明示的に許可する必要があります。空の許可リストは、書き込みアクセスがないことを意味します。
ネットワーク分離 (allow-only パターン): デフォルトでは、すべてのネットワークアクセスが拒否されています。ドメインを明示的に許可する必要があります。allowedDomains リストが空の場合、ネットワークアクセスはありません。ネットワークトラフィックは、ホスト上で実行されているプロキシサーバーを介してルーティングされます:
- Linux: リクエストは、Unix ドメインソケットを介してファイルシステム経由でルーティングされます。サンドボックス化されたプロセスのネットワーク名前空間は完全に削除されるため、すべてのネットワークトラフィックはホスト上で実行されているプロキシ (サンドボックス内にバインドマウントされた Unix ソケットで待ち受け) を通過する必要があります。
- macOS: Seatbelt プロファイルは、特定の localhost ポートへの通信のみを許可します。プロキシはこのポートで待ち受けし、すべてのネットワークアクセスのための制御されたチャネルを提供します。
- Windows: マシン全体の WFP フィルターセットは、
srt-sandboxアカウントから発信されるすべての送信接続を、プロキシポート範囲へのループバックを除いてブロックします。プロキシはその範囲内で待ち受けし、すべてのネットワークアクセスのための制御されたチャネルを提供します。
HTTP/HTTPS (HTTP プロキシ経由) とその他の TCP トラフィック (SOCKS5 プロキシ経由) はどちらも、ドメインの許可リストと拒否リストを適用するこれらのプロキシによって仲介されます。
Claude Code のサンドボックス化の詳細については、以下を参照してください:
- Claude Code Sandboxing Documentation
- Beyond Permission Prompts: Making Claude Code More Secure and Autonomous
アーキテクチャ```
src/ ├── index.ts # Library exports ├── cli.ts # CLI entrypoint (srt command) ├── utils/ # Shared utilities │ ├── debug.ts # Debug logging │ ├── settings.ts # Settings reader (permissions + sandbox config) │ ├── platform.ts # Platform detection │ └── exec.ts # Command execution utilities └── sandbox/ # Sandbox implementation ├── sandbox-manager.ts # Main sandbox manager ├── sandbox-schemas.ts # Zod schemas for validation ├── sandbox-violation-store.ts # Violation tracking ├── sandbox-utils.ts # Shared sandbox utilities ├── http-proxy.ts # HTTP/HTTPS proxy for network filtering ├── socks-proxy.ts # SOCKS5 proxy for network filtering ├── linux-sandbox-utils.ts # Linux bubblewrap sandboxing ├── macos-sandbox-utils.ts # macOS sandbox-exec sandboxing └── windows-sandbox-utils.ts # Windows srt-win sandboxing
## 使用方法
### CLIツールとして
`srt` コマンド(Anthropic Sandbox Runtime)は、任意のコマンドをセキュリティ境界でラップします:```bash
# Run a command in the sandbox
srt echo "hello world"
# With debug logging
srt --debug curl https://example.com
# Specify custom settings file
srt --settings /path/to/srt-settings.json npm install
ライブラリとして```typescript
import { SandboxManager, type SandboxRuntimeConfig, } from '@anthropic-ai/sandbox-runtime' import { spawn } from 'child_process'
// Define your sandbox configuration const config: SandboxRuntimeConfig = { network: { allowedDomains: ['example.com', 'api.github.com'], deniedDomains: [], }, filesystem: { denyRead: ['~/.ssh'], allowWrite: ['.', '/tmp'], denyWrite: ['.env'], }, }
// Initialize the sandbox (starts proxy servers, etc.) await SandboxManager.initialize(config)
// Wrap a command with sandbox restrictions const sandboxedCommand = await SandboxManager.wrapWithSandbox( 'curl https://example.com', )
// Execute the sandboxed command const child = spawn(sandboxedCommand, { shell: true, stdio: 'inherit' })
// Handle exit and cleanup after child process completes
child.on('exit', async code => {
console.log(Command exited with code ${code})
// Cleanup when done (optional, happens automatically on process exit)
await SandboxManager.reset()
})
**違反の帰属(`commandId` / `commandText`)。** ラップされたコマンドの実行中に観測された違反(seatbelt のログ行、seccomp イベント、プロキシ拒否)は、帰属キーの下に保存され、`annotateStderrWithSandboxFailures(key, stderr)` / `getViolationsForCommand(key)` はその同じキーでそれらを検索します。デフォルトでは、キーはラップされた文字列そのものです。代わりに、不透明な呼び出しごとの `commandId`(例: ツール使用 ID)を渡してキー付けしてください — 推奨: キーは最初の 100 文字で比較されるため、共通のプレフィックスを共有する長いコマンドは、そうしないと相互に属性が混同され、同じテキストの再実行が以前の実行のイベントを引き継ぐことになります。実行する文字列が、呼び出しが *表す* コマンドではない場合(例: 組み立てた `source <snapshot> && eval '<cmd>'` をラップする場合)、`commandText: '<cmd>'` も渡してください。これは `ignoreViolations` のコマンドパターンが照合する対象であり、各違反がその `command` として報告する内容でもあります。```typescript
const wrapped = await SandboxManager.wrapWithSandbox(
assembledCommand, // what actually runs
undefined,
undefined,
undefined,
{ commandId: invocationId, commandText: rawCommand },
)
// ... run it ...
const annotated = SandboxManager.annotateStderrWithSandboxFailures(invocationId, stderr)
利用可能なエクスポート```typescript
// Main sandbox manager export { SandboxManager } from '@anthropic-ai/sandbox-runtime'
// Violation tracking export { SandboxViolationStore } from '@anthropic-ai/sandbox-runtime'
// TypeScript types export type { SandboxRuntimeConfig, NetworkConfig, FilesystemConfig, IgnoreViolationsConfig, SandboxAskCallback, FsReadRestrictionConfig, FsWriteRestrictionConfig, NetworkRestrictionConfig, } from '@anthropic-ai/sandbox-runtime'
## 設定
### 設定ファイルの場所
デフォルトでは、サンドボックスランタイムは `~/.srt-settings.json` で設定を探します。`--settings` フラグを使用してカスタムパスを指定できます:```bash
srt --settings /path/to/srt-settings.json <command>
完全な設定例```json
{ "network": { "allowedDomains": [ "github.com", ".github.com", "lfs.github.com", "api.github.com", "npmjs.org", ".npmjs.org" ], "deniedDomains": ["malicious.com"], "allowUnixSockets": ["/var/run/docker.sock"], "allowLocalBinding": false }, "filesystem": { "denyRead": ["~/.ssh"], "allowRead": [], "allowWrite": [".", "src/", "test/", "/tmp"], "denyWrite": [".env", "config/production.json"] }, "ignoreViolations": { "*": ["/usr/bin", "/System"], "git push": ["/usr/bin/nc"], "npm": ["/private/tmp"] }, "enableWeakerNestedSandbox": false, "enableWeakerNetworkIsolation": false, "allowAppleEvents": false }
### 設定オプション
#### ネットワーク設定
**許可のみパターン**を採用しており、デフォルトではすべてのネットワークアクセスが拒否されます。
- `network.allowedDomains` - 許可されるドメインの配列(`*.example.com` のようなワイルドカードに対応)。空の配列 = ネットワークアクセスなし。オプションの `:port` サフィックス(`api.example.com:443`、`*.example.com:8443`)を付けると、そのエントリはその宛先ポートに限定されます。ポート指定のないエントリは任意のポートに一致します。
- IPv6リテラルはRFC 3986形式で角括弧で囲む必要があります: `[::1]`、`[2001:db8::1]:443`。角括弧で囲まれていないマルチコロンエントリは曖昧として拒否されます(`2001:db8::1:443` 自体は有効なアドレスです)。
- `network.deniedDomains` - 拒否されるドメインの配列(最初にチェックされ、`allowedDomains` よりも優先されます)。`:port` サフィックスは同じで、単独の `*`(または `*:22`)はすべて拒否として受け入れられます。
- `network.deniedDomainReasons` - `deniedDomains` エントリ(完全一致で照合)から、そのエントリが接続を拒否したときに `<sandbox_violations>` 行に表示されるモデル向けの理由へのオプションのマップ。何がブロックされたかと、承認された代替手段を指定します(例: `{"github.com:22": "SSH pushes to GitHub are blocked; use an https:// remote"}`)。理由のないエントリは一般的な理由を報告します。SSH宛先(ポート22)の場合、理由はインバンドでも配信されます。認証なしSOCKS ProxyCommand(例: BSD `nc -X 5`)を通じてトンネリングされたSSHクライアントは、鍵交換前のSSH切断を受け取り、その説明が理由となります。OpenSSHはこれをそのまま表示するため、そのような理由は約400 ASCII文字未満に保ち、命令形で始めてください。OpenSSHは非ASCIIを切り詰めてエスケープするためです。
- `network.allowLocalBinding` - ローカルポートへのバインドを許可します(boolean、デフォルト: false)
**TLS終端** (`network.tlsTerminate`、実験的): 設定すると、HTTPS CONNECTがプロセス内で終端され、SRTが復号化されたリクエストを参照(および `network.filterRequest` を介してフィルタリング)できるようになります。サンドボックス化されたプロセスは、MITM CA(`caCertPath`/`caKeyPath`、省略時は一時的なCA)とホストの通常のルートを含むトラストバンドルを指すように設定されるため、プロキシ発行の証明書と実際のアップストリーム証明書の両方が検証されます。
- `network.tlsTerminate.excludeDomains` - **終端されない**ドメインパターン(`allowedDomains` と同じ構文)。一致するCONNECTは代わりに透過的にトンネリングされます。それらは依然としてドメイン許可リストの対象ですが、サンドボックス内のクライアントは実際のアップストリームとの独自のTLSハンドシェイクを完了し、`filterRequest` / 資格情報注入はそれらのHTTPSトラフィックには適用されません。TLS終端が根本的に破綻する次の2つのケースにこれを使用します:
- **mTLSアップストリーム** - サンドボックス内のクライアントだけがクライアント証明書を保持しているため、プロキシはその代わりに接続を作り直すことができません。
- **証明書ピン留めクライアント** - アップストリームのIDを自身で検証するクライアント(カスタムCA、SANピン留め)で、MITM証明書を拒否します。
- `network.tlsTerminate.extraCaCertPaths` - そのトラストバンドルに追加されるPEM CA証明書ファイルへのパス。MITM CAとホストの通常のルートの後に追加されます。除外(非終端)されたホストはサンドボックス内のクライアントによって検証され、SRTが設定するトラスト環境変数(`SSL_CERT_FILE`、`GIT_SSL_CAINFO`、...)は各ツール自身のトラスト設定を_置き換える_ため、サイトローカルルート(例: 内部mTLS CA)はバンドルに含まれている必要があります。そうでなければそれらのホストは決して検証できません。各ファイルの`CERTIFICATE`ブロックのみがバンドルにコピーされます(それ以外、例えば結合PEM内の秘密鍵は、サンドボックスに公開されることはありません)。存在しない、読み取れない、またはPEM `CERTIFICATE`ブロックを含まないファイルはスキップされるため、一部のホストにしか存在しないパスをリストしても安全です。```json
{
"network": {
"allowedDomains": ["*.example.com", "internal-mtls.example.net"],
"deniedDomains": [],
"tlsTerminate": {
"excludeDomains": ["internal-mtls.example.net"],
"extraCaCertPaths": ["/etc/internal-mtls-roots.pem"]
}
}
}
Unix ソケット設定 (プラットフォーム固有の動作):
| 設定 | macOS | Linux |
|---|---|---|
allowUnixSockets: string[] | ソケットパスの許可リスト | 無視 (seccomp はパスでフィルタリングできない) |
allowAllUnixSockets: boolean | すべてのソケットを許可 | seccomp ブロッキングを無効化 |
Unix ソケットは、両プラットフォームでデフォルトでブロックされています。
- macOS: 特定のパスを許可するには
allowUnixSocketsを使用します(例:["/var/run/docker.sock"])。または、すべてを許可するにはallowAllUnixSockets: trueを使用します。 - Linux: ブロッキングは seccomp フィルター(x64/arm64 のみ)を使用します。seccomp が利用できない場合、ソケットは制限なしになり、警告が表示されます。ブロッキングを明示的に無効にするには
allowAllUnixSockets: trueを使用します。
ファイルシステム設定
2 つの異なるパターンを使用します:
読み取り制限 (deny-then-allow パターン) - デフォルトではすべての読み取りが許可されます:
filesystem.denyRead- 読み取りアクセスを拒否するパスの配列。空の配列 = 完全な読み取りアクセス。filesystem.allowRead- 拒否された領域内で読み取りアクセスを再許可するパスの配列(denyRead よりも優先されます)。注: これは書き込みとは逆で、書き込みではdenyWriteがallowWriteよりも優先されます。
書き込み制限 (allow-only パターン) - デフォルトではすべての書き込みが拒否されます:
filesystem.allowWrite- 書き込みアクセスを許可するパスの配列。空の配列 = 書き込みアクセスなし。filesystem.denyWrite- 許可されたパス内で書き込みアクセスを拒否するパスの配列(allowWrite よりも優先されます)
パス構文 (macOS):
macOS では、パスは .gitignore 構文と同様の git スタイルの glob パターンをサポートしています:
*-/を除く任意の文字に一致(例:*.tsはfoo.tsに一致するがfoo/bar.tsには一致しない)**-/を含む任意の文字に一致(例:src/**/*.tsはsrc/内のすべての.tsファイルに一致する)?-/を除く任意の 1 文字に一致(例:file?.txtはfile1.txtに一致する)[abc]- セット内の任意の文字に一致(例:file[0-9].txtはfile3.txtに一致する)
例:
"allowWrite": ["src/"]-src/ディレクトリ全体への書き込みを許可"allowWrite": ["src/**/*.ts"]-src/およびサブディレクトリ内のすべての.tsファイルへの書き込みを許可"denyRead": ["~/.ssh"]- SSH ディレクトリへの読み取りを拒否"denyRead": ["/Users"], "allowRead": ["."]-/Users全体への読み取りを拒否し、カレントディレクトリのみ再許可する"denyWrite": [".env"]-.envファイルへの書き込みを拒否(カレントディレクトリが許可されていても)
パス構文 (Linux):
Linux は現在、glob マッチングをサポートしていません。 リテラルパスのみを使用してください:
"allowWrite": ["src/"]-src/ディレクトリへの書き込みを許可"denyRead": ["/home/user/.ssh"]- SSH ディレクトリへの読み取りを拒否"denyRead": ["/home"], "allowRead": ["."]-/home全体への読み取りを拒否し、カレントディレクトリのみ再許可する
すべてのプラットフォーム:
- パスは絶対パス(例:
/home/user/.ssh)またはカレントワーキングディレクトリからの相対パス(例:./src)にできます ~はユーザーのホームディレクトリに展開されます
その他の設定
ignoreViolations- コマンドパターンを、違反を無視するパスの配列にマッピングするオブジェクトenableWeakerNestedSandbox- Docker 環境向けの弱いサンドボックスモードを有効にする(boolean、デフォルト: false)enableWeakerNetworkIsolation- macOS サンドボックス内でcom.apple.trustd.agentへのアクセスを許可する(boolean、デフォルト: false)。これは、httpProxyPortを MITM プロキシおよびカスタム CA と共に使用する場合に、Go プログラム(gh、gcloud、terraform、kubectlなど)が TLS 証明書を検証するために必要です。セキュリティ警告: これを有効にすると、trustd サービスを介した潜在的なデータ流出経路が開かれます。allowAppleEvents- macOS サンドボックスから Apple Events および Launch Services の open リクエストの送信を許可する(boolean、デフォルト: false)。これがないと、open、osascript、および AppleScript を介して URL を開いたり他のアプリをスクリプト制御したりするものはすべて、AppleScript エラー-600("Application isn't running")または LaunchServices エラー(-10822、-54)で失敗します。セキュリティ警告: これを有効にすると、サンドボックスはコード実行の分離を提供しなくなります。サンドボックス内のコマンドは、ユーザープロンプトなしでopenを介して他のアプリケーションを起動でき、起動されたものはすべてサンドボックスのファイルシステムおよびネットワーク制限の外で実行されます。Apple Events を介した既に実行中のアプリのスクリプト制御は、ユーザーのアプリごとの TCC 自動化同意によってさらに制限されます。埋め込み側は、このオプションを信頼できるユーザーレベルの設定からのみ取得する必要があります — チェックアウトしたリポジトリ内のプロジェクトローカルファイルから取得しては決してなりません。そうしたファイルから取得すると、攻撃者が作成したプロジェクトが自身のサンドボックス権限を昇格させる可能性があります。
一般的な設定レシピ
GitHub アクセスを許可する (必要なすべてのエンドポイント):```json { "network": { "allowedDomains": [ "github.com", "*.github.com", "lfs.github.com", "api.github.com" ], "deniedDomains": [] }, "filesystem": { "denyRead": [], "allowWrite": ["."], "denyWrite": [] } }
**特定のディレクトリに制限する:**```json
{
"network": {
"allowedDomains": [],
"deniedDomains": []
},
"filesystem": {
"denyRead": ["~/.ssh"],
"allowWrite": [".", "src/", "test/"],
"denyWrite": [".env", "secrets/"]
}
}
ワークスペースのみのファイルシステムアクセス(ワークスペース外の読み取りを拒否):```json { "network": { "allowedDomains": [], "deniedDomains": [] }, "filesystem": { "denyRead": ["/Users"], "allowRead": ["."], "allowWrite": ["."], "denyWrite": [] } }
これにより、`/Users`(Linuxでは`/home`)配下の読み取りは拒否され、その後、現在の作業ディレクトリが再び許可されます。システムパス(`/usr`、`/lib`など)は読み取り可能なままです。
### よくある問題とヒント
**Jestの実行:** サンドボックス違反を避けるには、`--no-watchman`フラグを使用してください:```bash
srt "jest --no-watchman"
Watchman はサンドボックス境界の外にあるファイルにアクセスするため、権限エラーが発生します。これを無効にすると、Jest は代わりに組み込みのファイルウォッチャーで実行できます。
プラットフォーム対応
- macOS: カスタムプロファイルで
sandbox-execを使用(追加の依存関係は不要) - Linux: コンテナ化に
bubblewrap(bwrap) を使用 - Windows: アルファ版 — バンドルされた
srt-win.exeヘルパーを使用(追加の依存関係は不要)。セットアップ、セキュリティモデル、既知の制限については、下記の Windows (アルファ) を参照してください。
プラットフォーム固有の依存関係
Linux に必要なもの:
bubblewrap- コンテナランタイム- Ubuntu/Debian:
apt-get install bubblewrap - Fedora:
dnf install bubblewrap - Arch:
pacman -S bubblewrap
- Ubuntu/Debian:
socat- プロキシブリッジ用のソケットリレー- Ubuntu/Debian:
apt-get install socat - Fedora:
dnf install socat - Arch:
pacman -S socat
- Ubuntu/Debian:
ripgrep- 拒否パス検出用の高速検索ツール- Ubuntu/Debian:
apt-get install ripgrep - Fedora:
dnf install ripgrep - Arch:
pacman -S ripgrep
- Ubuntu/Debian:
Ubuntu 24.04+ の注意: これらのリリースでは、デフォルトで kernel.apparmor_restrict_unprivileged_userns が有効になっており、unshare(CLONE_NEWUSER) は許可されますが、結果の名前空間からケーパビリティが削除されます。bubblewrap と seccomp 分離レイヤーの両方に、ケーパビリティを持つユーザー名前空間が必要です。制限を無効にするには:```bash
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
または、関連するバイナリに `userns` を許可する AppArmor プロファイルを追加します。
**オプションの Linux 依存関係(seccomp フォールバック用):**
このパッケージには、x86-64 および arm アーキテクチャ向けの事前生成済み seccomp BPF フィルターが含まれています。これらの依存関係は、事前生成済みフィルターが利用できない別のアーキテクチャを使用している場合にのみ必要です。
- `gcc` または `clang` - C コンパイラ
- `libseccomp-dev` - Seccomp ライブラリ開発ファイル
- Ubuntu/Debian: `apt-get install gcc libseccomp-dev`
- Fedora: `dnf install gcc libseccomp-devel`
- Arch: `pacman -S gcc libseccomp`
**macOS での要件:**
- `ripgrep` - 拒否パス検出用の高速検索ツール
- Homebrew でインストール: `brew install ripgrep`
- または以下からダウンロード: https://github.com/BurntSushi/ripgrep/releases
**Windows での要件:**
- 追加の依存関係はありません。`srt-win.exe` ヘルパー(x64 および arm64)は npm パッケージに同梱されています。一度だけ管理者権限での `windows-install` ステップが必要です — 以下を参照してください。
## Windows(アルファ版)
Windows サポートは **アルファ版** です。サンドボックス化されたプロセスは、専用の `srt-sandbox` ローカルユーザーアカウントで実行され、ネイティブの Windows セキュリティプリミティブによって呼び出し元ユーザーから分離されます — サンドボックスアカウントの SID をキーとする Windows Filtering Platform (WFP) エグレスフェンスと、構成されたファイルシステムパスへのアクセスをその SID に許可または拒否するセッションごとの明示的な ACE です。
### セットアップ
マシンごとに 1 回実行します(自己昇格、UAC プロンプトが 1 回表示されます):```powershell
npx @anthropic-ai/sandbox-runtime windows-install
これは、srt-sandbox ローカルユーザーアカウント(ランダムなパスワードは DPAPI で暗号化され、%LOCALAPPDATA%\sandbox-runtime\state.db に保存される)、sandbox-runtime-users ローカルグループをプロビジョニングし、srt-sandbox の SID をキーとするマシン全体の WFP フィルターセットをインストールします。これは冪等です。再実行するとサンドボックスアカウントのパスワードがローテーションされ、フィルターセットが再調整されます。
ログアウトは不要です。 WFP フィルターは専用のサンドボックスアカウントの SID をキーとするため、自身のネットワーク、サービス、およびマシン上の他のすべてのプリンシパルには影響しません。
インストール後、SandboxManager.initialize() と srt CLI は他のプラットフォームと同様に動作します。initialize() はサンドボックスアカウントと WFP フェンスが有効であることを確認し、有効でない場合は対処可能なエラーで失敗します。
プログラムによるインストール/アンインストールは、installWindowsSandbox() / uninstallWindowsSandbox() としてエクスポートされています。
セキュリティモデル
サンドボックス化されたコマンドは、呼び出し元ユーザーとしてではなく、srt-sandbox アカウントとして実行されます。同梱の srt-win.exe ヘルパーは 2 ホップの起動を行います。ブローカーが CreateProcessWithLogonW を呼び出して srt-sandbox としてランナーを起動し、ランナーはジョブオブジェクト内の制限付きトークンの下でターゲットを起動します。子プロセスは、サンドボックスアカウントの分離されたプロファイル(%USERPROFILE%、%TEMP%、HKCU)と、ブローカーの PATH と生成されたプロキシ変数のみを重ねた新しい環境を継承します。
異なるユーザー SID で実行することで、surrogate-spawn 系のエスケープ(タスクスケジューラ、ブローカー所有プロセスへの PROC_THREAD_ATTRIBUTE_PARENT_PROCESS、BITS、RunAs="Interactive User" によるプロセス外 COM)を構造的に遮断します。子プロセスが帯域外で生成できたプロセスも依然として srt-sandbox の SID を保持するため、WFP の送信フェンスの対象であり続け、呼び出し元ユーザーのファイルに対する権限はありません。
ネットワーク分離は、FWPM_LAYER_ALE_AUTH_CONNECT_V4/V6 に設定された 2 つのフィルターからなる WFP セットです。設定されたプロキシポート範囲(デフォルト 60080–60089)内のループバック宛先に対する PERMIT と、トークンが srt-sandbox の SID を保持するすべての接続に対する BLOCK です。サンドボックス化されたプロセスがインターネットに到達できるのは、その範囲で待ち受ける JS HTTP/SOCKS5 プロキシを経由する場合のみです。プロキシ環境を除去して直接接続するプロセスは、カーネルでブロックされます。
ファイルシステム分離は、NTFS の随意アクセス制御リスト(DACL)によって強制されます。srt-sandbox アカウントは呼び出し元ユーザーのファイルに対する固有の権限を持たないため、initialize() 時にサンドボックスは srt-sandbox の SID のみに対する追加的で継承される明示的な ACE を書き込みます。パスの既存のセキュリティ記述子を書き換えたり置き換えたりすることはありません。
filesystem.allowWrite→ 継承されるMODIFYALLOW ACE(READ|WRITE|EXECUTE|DELETE、ただしFILE_DELETE_CHILDは付与しない)。サンドボックス化されたプロセスは作業ツリー内でファイルを作成、変更、削除できます。付与からFILE_DELETE_CHILDを除外することは、後述の拒否スタンプに対する多層防御であり、ツリールートを保護するものではありません。filesystem.allowRead→ 継承されるREAD|EXECUTEALLOW ACEfilesystem.denyRead/filesystem.denyWrite→ 対象に対する継承される DENY ACE に加え、その親に対する継承されるFILE_DELETE_CHILDDENY。作業ツリーへの付与でFILE_DELETE_CHILDを除外していることと合わせて、サンドボックス化されたプロセスが親ディレクトリ経由で拒否されたパスを名前変更または削除することを防ぎます。
reset() は、このセッションで追加されたすべての ACE を削除します(state.db を介して並行するホスト間で参照カウントされます。異常終了後は、次回の initialize() のクラッシュリカバリ処理がクリーンアップします)。ディレクトリ対象もサポートされています(ACE はサブツリー全体に継承されます)。グロブパターンは initialize() の時点で具体的なパスに展開されるため、後から現れる一致パスは対象外です。
Windows での TLS 終端
network.tlsTerminate では、MITM CA がサンドボックスユーザーの CurrentUser\Root 証明書ストアに存在している必要があります(schannel は System32\curl.exe、PowerShell の Invoke-WebRequest、.NET、およびデフォルトバックエンドの git が使用する TLS バックエンドで、環境変数ではなく OS ストアのみを信頼します)。これはインストール時の手順であり、windows-install とは別です:```typescript
import { windowsTrustCa } from '@anthropic-ai/sandbox-runtime'
windowsTrustCa('/path/to/mitm-ca.crt') // or: srt-win user trust-ca
`initialize()` はセッション CA のサムプリントとインストール済みのものを比較し、不一致の場合は具体的なメッセージとともに失敗するため、古いインストール時 CA がサイレントにサンドボックス内の TLS を壊すことはありません。
OpenSSL バックエンドのクライアント(msys2 の `curl`、`git -c http.sslBackend=openssl`、Node、Python、cargo)は、環境変数によるトラストレイヤーでカバーされます。macOS/Linux で使用されるものと同じトラストバンドルが、`NODE_EXTRA_CA_CERTS`、`SSL_CERT_FILE`、`CURL_CA_BUNDLE`、`GIT_SSL_CAINFO`、`CARGO_HTTP_CAINFO` などを介してサンドボックスに渡され、バンドルパスは セッションの `allowRead` 許可に追加されるため、サンドボックスアカウントがそれを開くことができます。
### Windows 固有の設定
クロスプラットフォームの `filesystem` と `network` ブロックは、上記のとおり適用されます。Windows 専用設定は `windows` の下にあります:
- `windows.proxyPortRange` — JS プロキシが内部でバインドする `[low, high]` の両端を含むポート範囲。`windows-install --proxy-port-range` に渡す範囲(デフォルト `[60080, 60089]`)と**一致している必要があります** — WFP ループバック PERMIT はその範囲のみをカバーします。
- `windows.sublayerGuid` — フィルターがインストールされた WFP サブレイヤー GUID。省略するとコンパイル時のデフォルトを使用します。エンタープライズツールがカスタムサブレイヤーの下にフィルターをインストールした場合のみ設定します。
- `windows.srtWin.path` — `srt-win` バイナリへのパス。省略するとパッケージ化された `vendor/srt-win/<arch>/srt-win.exe` を使用します。`srt-win` の CLI をマルチコールバイナリに埋め込む場合に設定します。その場合、スポーン時に `--srt-win` が `argv[1]` として渡されるため、埋め込み側のディスパッチャーが `srt_win::run_from_args` にルーティングできます。
### 既知の制限事項
- **schannel での証明書失効。** CryptoAPI の CRL/OCSP フェッチは、呼び出し元のトークンで WinHTTP を介して実行され、プロキシ環境を無視するため、WFP の送信フェンスによってブロックされます。デフォルトで失効確認が有効な schannel を使用するツールは、ツールごとに失効確認を無効にしない限り、`CRYPT_E_REVOCATION_OFFLINE`(`0x80092013`)で失敗します: `curl --ssl-no-revoke`、`git -c http.schannelCheckRevoke=false`、`CARGO_HTTP_CHECK_REVOKE=false`。`Invoke-WebRequest`、.NET の `HttpClient`、`gh` はデフォルトでは失効確認を行わないため影響を受けません。この回避策を不要にするために、ループバックプロキシから配信される CRL 配布ポイントが計画されています。
- **ユーザー単位のツールインストールには到達できません。** サンドボックス化されたプロセスはあなたではなく `srt-sandbox` として実行されるため、プロファイルの下にインストールされたツール(nvm/fnm 管理の Node、ユーザー単位の `winget`/Scoop パッケージ、`pip install --user`、`%LOCALAPPDATA%\Programs\…`)は継承された `PATH` 上では解決されますが、サンドボックスアカウントでは開くことができません。マシン全体へのインストール(`Program Files`、`choco`/`winget --scope machine`)を優先するか、特定のプロファイルパスを `filesystem.allowRead` に追加してください。
- **実行ごとの `filesystem.allowRead` / `filesystem.allowWrite` オーバーライドはサポートされていません。** セッションレベルの `allowRead`/`allowWrite`(`initialize()` に渡す設定内)は上記のとおり機能します。`wrapWithSandbox` の `customConfig` でコマンドごとに渡すと例外が発生します — 許可は `initialize()` で `srt-win acl grant` によりセッション全体に適用され、`srt-win exec` は実行ごとの拒否のみを公開します。
- **`proxyAuthToken` はランナーのコマンドラインで見えます。** プロキシ環境(`HTTP_PROXY=http://srt:<token>@127.0.0.1:…` を含む)は、`srt-win exec` の argv 上の `--env` 引数として 2 ホップランナーに渡されるため、`PROCESS_QUERY_LIMITED_INFORMATION` のためにランナープロセスを開くことができるローカルの任意のプリンシパルがトークンを読み取れます。トークンはサンドボックス化されたプロセスがループバックプロキシに対して認証できるように存在するため、サンドボックス自体にとっては秘密ではありません。シングルユーザーの開発マシンでは一般的に許容されますが、共有ホストではプロキシ許可リストを同じセッションの他のプリンシパルから到達可能なものとして扱ってください。
- **システムリゾルバーによる DNS 解決はフェンスされません。** `getaddrinfo()` は `NETWORK SERVICE` として実行される `Dnscache` サービスによって処理されるため、サンドボックス化されたプロセスからの後続の `connect()` がブロックされていても名前解決は成功します。独自の UDP/53 を行うツール(`nslookup`、`dig`)はフェンスされます。これは macOS の動作を反映しています。
### アンインストール```powershell
npx @anthropic-ai/sandbox-runtime windows-uninstall
WFP フィルター セット、srt-sandbox アカウントとそのプロファイル、sandbox-runtime-users グループを削除し、state.db から資格情報/セットアップ マーカーを消去します(UAC プロンプトが 1 回表示されます)。%LOCALAPPDATA%\sandbox-runtime\state.db 自体はそのまま残されます(これは ACL スタンプされたブローカーのみがアクセス可能です)。完全に掃除するには、ディレクトリを手動で削除してください。
開発```bash
Install dependencies
npm install
Build the project
npm run build
Run tests
npm test
Type checking
npm run typecheck
Lint code
npm run lint
Format code
npm run format
### Seccomp バイナリのビルド
BPF フィルタと `apply-seccomp` ローダーは、`vendor/seccomp-src/` 内の C ソースから `npm run build:seccomp` によってコンパイルされます(Linux のみ。`gcc` と `libseccomp-dev` が必要)。CI は各 Linux アーキテクチャのテスト前にこれを実行し、リリースワークフローは両アーキテクチャをビルドして公開パッケージにバンドルします。
## 実装の詳細
### ネットワーク分離アーキテクチャ
サンドボックスはホストマシン上で HTTP および SOCKS5 プロキシサーバーを実行し、権限ルールに基づいてすべてのネットワークリクエストをフィルタリングします。
1. **HTTP/HTTPS トラフィック**: HTTP プロキシサーバーがリクエストをインターセプトし、許可/拒否されたドメインに対して検証します
2. **その他のネットワークトラフィック**: SOCKS5 プロキシが他のすべての TCP 接続(SSH、データベース接続など)を処理します
3. **権限の適用**: プロキシは設定の `permissions` ルールを適用します
**プラットフォーム固有のプロキシ通信:**
- **Linux**: リクエストはファイルシステム経由で Unix ドメインソケットを通じてルーティングされます(ブリッジングには `socat` を使用)。ネットワーク名前空間は bubblewrap コンテナから削除され、すべてのネットワークトラフィックがプロキシを通過しなければならないようになります。
- **macOS**: Seatbelt プロファイルは、プロキシがリッスンする特定の localhost ポートへの通信のみを許可します。その他のネットワークアクセスはすべてブロックされます。
- **Windows**: WFP の `ALE_AUTH_CONNECT` フィルタは、設定されたプロキシポート範囲へのループバックを除き、`srt-sandbox` アカウントからのすべての送信接続をブロックします。プロキシはその範囲内にバインドされます。環境変数(`HTTP_PROXY`、`HTTPS_PROXY`、`ALL_PROXY`、…)はツールをプロキシに向けますが、境界となるのは WFP フィルタです。これらを無視または未設定にするプロセスでも、依然としてフェンスで囲まれています。
### ファイルシステムの分離
ファイルシステムの制限は OS レベルで適用されます。
- **macOS**: 動的に生成された Seatbelt プロファイル(許可された読み取り/書き込みパスを指定)とともに `sandbox-exec` を使用します
- **Linux**: バインドマウント付きの `bubblewrap` を使用し、構成に基づいてディレクトリを読み取り専用または読み書き可能としてマークします
- **Windows**: 構成されたパスに対して `srt-sandbox` SID の加算的な `(OI)(CI)` 明示的 ACE を書き込み(`allowRead`/`allowWrite` では ALLOW、`denyRead`/`denyWrite` では DENY)、`reset()` でそれらを削除します
**デフォルトのファイルシステム権限:**
- **読み取り**(拒否→許可): デフォルトではすべての場所で許可されます。広い領域を拒否してから、その中の特定のパスを再許可できます。`allowRead` は `denyRead` よりも優先されます。
- 例: `denyRead: ["~/.ssh"]` は SSH キーへのアクセスをブロックします
- 例: `denyRead: ["/Users"], allowRead: ["."]` は `/Users` 全体のうちワークスペース以外をブロックします
- 空の `denyRead: []` = 完全な読み取りアクセス(拒否なし)
- **書き込み**(許可のみ): デフォルトではすべての場所で拒否されます。明示的にパスを許可する必要があります。
- 例: `allowWrite: [".", "/tmp"]` はカレントディレクトリと /tmp への書き込みを許可します
- 空の `allowWrite: []` = 書き込みアクセスなし(許可なし)
- `denyWrite` は許可されたパス内に例外を作成します(拒否が優先されます)
**読み取りと書き込みで優先順位は意図的に逆になっています:** `allowRead` は `denyRead` を上書きし、`denyWrite` は `allowWrite` を上書きします。これにより、拒否された領域内に読み取り可能な領域を切り出し、書き込み可能な領域内に保護された領域を切り出すことができます。
### 必須拒否パス(自動保護ファイル)
特定の機密ファイルとディレクトリは、許可された書き込みパス内にある場合でも、**書き込みが常にブロックされます**。これにより、サンドボックスエスケープや設定改ざんに対する多層防御が提供されます。
**常にブロックされるファイル:**
- シェル設定ファイル: `.bashrc`, `.bash_profile`, `.zshrc`, `.zprofile`, `.profile`
- Git 設定ファイル: `.gitconfig`, `.gitmodules`
- その他の機密ファイル: `.ripgreprc`, `.mcp.json`
**常にブロックされるディレクトリ:**
- IDE ディレクトリ: `.vscode/`, `.idea/`
- Claude 設定ディレクトリ: `.claude/commands/`, `.claude/agents/`
- Git フックと設定: `.git/hooks/`, `.git/config`
これらのパスは自動的にブロックされます - `denyWrite` に追加する必要はありません。たとえば、`allowWrite: ["."]` の場合でも、`.bashrc` や `.git/hooks/pre-commit` への書き込みは失敗します。```bash
$ srt 'echo "malicious" >> .bashrc'
/bin/bash: .bashrc: Operation not permitted
$ srt 'echo "bad" > .git/hooks/pre-commit'
/bin/bash: .git/hooks/pre-commit: Operation not permitted
注意(Linux): Linuxでは、必須拒否パスは既に存在するファイルのみをブロックします。これらのパターンに一致する存在しないファイルは、bubblewrapのバインドマウント方式ではブロックできません。macOSはグロブパターンを使用しており、既存ファイルと新規ファイルの両方をブロックします。
Linuxの検索深度: Linuxでは、サンドボックスはripgrepを使用して、許可された書き込みパス内のサブディレクトリにある危険なファイルをスキャンします。デフォルトでは、パフォーマンスのために最大3レベルまでの深さを検索します。これはmandatoryDenySearchDepthで設定できます:```json
{
"mandatoryDenySearchDepth": 5,
"filesystem": {
"allowWrite": ["."]
}
}
- デフォルト: `3`(最大3レベルまで検索)
- 範囲: `1` から `10`
- 値が大きいほど保護は強化されますが、パフォーマンスは低下します
- CWD(深さ0)にあるファイルは、この設定に関係なく常に保護されます
### Unixソケット制限(Linux)
Linuxでは、サンドボックスはsyscallレベルでUnixドメインソケットの作成をブロックするために**seccomp BPF(Berkeley Packet Filter)**を使用します。これにより、プロセスがローカルIPC用に新しいUnixドメインソケットを作成するのを防ぐ追加のセキュリティレイヤーが提供されます(明示的に許可された場合を除く)。
**仕組み:**
1. **組み込みBPFフィルタ**: パッケージには、seccomp BPFフィルタが組み込まれた静的 `apply-seccomp` バイナリがx64およびarm64向けに同梱されています。フィルタはアーキテクチャ固有ですがlibc非依存のため、バイナリはglibcとmuslの両方で動作します。
2. **ランタイム検出**: サンドボックスはシステムのアーキテクチャを自動的に検出し、一致する `apply-seccomp` バイナリを使用します。
3. **syscallフィルタリング**: BPFフィルタは `socket()` syscallをインターセプトし、`EPERM` を返すことで `AF_UNIX` ソケットの作成をブロックします。これにより、サンドボックス化されたコードが新しいUnixドメインソケットを作成するのを防ぎます。
4. **apply-seccompバイナリを使用した2段階適用**:
- 外側のbwrapが、ファイルシステム、ネットワーク、PID名前空間の制限付きでサンドボックスを作成します
- ネットワークブリッジプロセス(socat)がサンドボックス内で起動します(Unixソケットが必要)
- apply-seccompがネストされたuser+PID+mount名前空間を作成し、`/proc` を再マウントします
- ネストされた名前空間内で、apply-seccompはPID 1(非ダンプ可能なinit/リーパー)として動作します
- apply-seccompはフォークし、`prctl()` を介してseccompフィルタを適用し、ユーザーコマンドをexecします
- ユーザーコマンドは、すべてのサンドボックス制限に加えてUnixソケット作成ブロック付きで実行されます
**PID名前空間の分離**: ネストされたPID名前空間により、ユーザーコマンドはseccompフィルタなしで実行されるプロセス(bwrapのinit、シェルラッパー、socatヘルパー)を認識またはアドレス指定できません。フィルタリングされていないヘルパーは `ptrace` や `/proc/N/mem` を介して到達できないため、`kernel.yama.ptrace_scope` に関係なくseccomp境界は維持されます。内側のPID 1は `PR_SET_DUMPABLE=0` を設定するため、こちらもptrace可能ではありません。ネストされた名前空間の作成に失敗した場合、apply-seccompは分離なしで実行するのではなく中止します。
**セキュリティ上の制限**: このフィルタは `socket(AF_UNIX, ...)` と `io_uring_setup`/`io_uring_enter`/`io_uring_register` syscallをブロックします(後者の3つは、Linux 5.19+の `IORING_OP_SOCKET` が `socket()` ルールをバイパスするためです)。親プロセスから継承された、または `SCM_RIGHTS` を介して渡されたUnixソケットファイルディスクリプタに対する操作は防止できません。ほとんどのサンドボックスシナリオでは、ソケット作成のブロックは不正なIPCを防ぐのに十分です。
**ランタイム依存関係ゼロ**: プリビルドの静的apply-seccompバイナリと事前生成されたBPFフィルタがx64およびarm64アーキテクチャ向けに同梱されています。ランタイムにコンパイルツールや外部依存関係は必要ありません。
**アーキテクチャサポート**: x64とarm64はプリビルドバイナリで完全にサポートされています。その他のアーキテクチャは現在サポートされていません。サポートされていないアーキテクチャでUnixソケットブロックなしのサンドボックス化を使用するには、設定で `allowAllUnixSockets: true` を設定してください。
### 違反の検出と監視
サンドボックス化されたプロセスが制限されたリソースにアクセスしようとすると:
1. **操作をブロック**します(OSレベルで `EPERM` エラーを返します)
2. **違反をログに記録**します(プラットフォーム固有のメカニズム)
3. **ユーザーに通知**します(Claude Codeでは、権限プロンプトがトリガーされます)
**macOS**: サンドボックスランタイムはmacOSのシステムサンドボックス違反ログストアを利用します。これにより、何が試行され、なぜブロックされたかに関する詳細情報を含むリアルタイム通知が提供されます。これはClaude Codeが違反検出に使用しているのと同じメカニズムです。```bash
# View sandbox violations in real-time
log stream --predicate 'process == "sandbox-exec"' --style syslog
Linux: Bubblewrapは組み込みの違反報告機能を提供しません。straceを使用してシステムコールをトレースし、ブロックされた操作を特定します:```bash
Trace all denied operations
strace -f srt 2>&1 | grep EPERM
Trace specific file operations
strace -f -e trace=open,openat,stat,access srt 2>&1 | grep EPERM
Trace network operations
strace -f -e trace=network srt 2>&1 | grep EPERM
### 上級: 独自プロキシを使用する
より高度なネットワークフィルタリングを行うには、組み込みのプロキシの代わりに独自のプロキシを使用するようにサンドボックスを設定できます。これにより、以下が可能になります:
- **トラフィック検査**: [mitmproxy](https://mitmproxy.org/) などのツールを使用してトラフィックを検査および変更できます
- **カスタムフィルタリングロジック**: 単純なドメイン許可リストを超えた複雑なルールを実装できます
- **監査ログ**: コンプライアンスやデバッグのためにすべてのネットワークリクエストを記録できます
**mitmproxy を使用した例:**```bash
# Start mitmproxy with custom filtering script
mitmproxy -s custom_filter.py --listen-port 8888
注記: 新しい構成形式では、カスタムプロキシ構成はまだサポートされていません。この機能は将来のリリースで追加される予定です。
重要なセキュリティ上の考慮事項: ドメインの許可リストを使用していても、データ持ち出し(エクスフィルトレーション)の経路が存在する可能性があります。たとえば、github.com を許可すると、プロセスは任意のリポジトリにプッシュできます。カスタム MITM プロキシと適切な証明書設定を使用すれば、特定の API 呼び出しを検査およびフィルタリングして、これを防ぐことができます。
セキュリティ上の制限
- ネットワークサンドボックスの制限: ネットワークフィルタリングシステムは、プロセスが接続を許可されるドメインを制限することによって動作します。プロキシを通過するトラフィックをそれ以外の方法で検査することはなく、ユーザーはポリシーで信頼できるドメインのみを許可するように責任を負います。
- Unix ソケットを介した権限昇格:
allowUnixSockets構成は、意図せず強力なシステムサービスへのアクセスを許可し、サンドボックスバイパスにつながる可能性があります。たとえば、/var/run/docker.sockへのアクセスを許可するために使用された場合、Docker ソケットを悪用して実質的にホストシステムへのアクセスが許可されます。ユーザーは、サンドボックスを通過させる Unix ソケットを慎重に検討することをお勧めします。 - ファイルシステム権限の昇格: 過度に広範なファイルシステム書き込み権限は、権限昇格攻撃を可能にする可能性があります。
$PATH内の実行可能ファイルを含むディレクトリ、システム構成ディレクトリ、またはユーザーのシェル構成ファイル(.bashrc、.zshrc)への書き込みを許可すると、他のユーザーやシステムプロセスがこれらのファイルにアクセスしたときに、異なるセキュリティコンテキストでのコード実行につながる可能性があります。 - Linux サンドボックスの強度: Linux 実装は強力なファイルシステムおよびネットワーク分離を提供しますが、特権名前空間なしで Docker 環境内で動作できるようにする
enableWeakerNestedSandboxモードも含まれています。このオプションはセキュリティを大幅に弱めるため、他の方法で追加の分離が強制される場合にのみ使用する必要があります。 - 弱いネットワーク分離(macOS):
enableWeakerNetworkIsolationオプションは、Go プログラムが macOS Security フレームワークを介して TLS 証明書を検証するために必要なcom.apple.trustd.agentへのアクセスを再び有効にします。これにより、trustd サービスを介したデータ持ち出しの潜在的な経路が開かれるため、Go の TLS 検証が必要な場合(たとえば、MITM プロキシとカスタム CA でhttpProxyPortを使用する場合)にのみ有効にする必要があります。 - Apple Events(macOS):
allowAppleEventsオプションは、Apple Events と Launch Services のオープンリクエストの送信((allow appleevent-send)、(allow lsopen)、およびcom.apple.coreservices.appleevents、com.apple.CoreServices.coreservicesd、com.apple.coreservices.quarantine-resolverの mach-lookup)を再び有効にします。これらはopen、osascript、および URL を開くヘルパーが必要とするものです。これらを許可すると、サンドボックス内のコマンドはユーザープロンプトなしで任意のアプリケーションを起動でき、起動されたアプリケーションは完全にサンドボックスの外で実行されるため、このオプションはコード実行の分離を弱めるだけでなく、完全に削除します。Apple Events を介した実行中のアプリケーションのスクリプト操作は、macOS TCC の自動化同意によってさらに制限されますが、openを介した起動は制限されません。サンドボックス内のコマンドが実際に URL やアプリケーションを開く必要がある場合にのみ、これを有効にしてください。
既知の制限と今後の課題
Linux プロキシバイパス: 現在、環境変数(HTTP_PROXY、HTTPS_PROXY、ALL_PROXY)を使用してトラフィックをプロキシ経由で誘導します。これはほとんどのアプリケーションで機能しますが、これらの変数を尊重しないプログラムでは無視され、インターネットに接続できなくなる可能性があります。
今後の改善点:
-
Proxychains サポート: Linux で
LD_PRELOADを使用したproxychainsのサポートを追加し、ネットワーク呼び出しをより低いレベルでインターセプトすることで、バイパスをより困難にします -
Linux 違反モニタリング: 違反ストアと統合された、
straceベースの自動違反検出を Linux 向けに実装します。現在、Linux ユーザーは違反を確認するために手動でstraceを実行する必要があります。macOS ではシステムログストアを介した自動違反モニタリングがあるのとは対照的です。