mirror of
https://github.com/anthropic-experimental/sandbox-runtime.git
synced 2026-06-09 03:24:07 +08:00
fix: use wildcard in allowLocalBinding seatbelt rules for IPv6 dual-stack compatibility
Modern runtimes like Java create IPv6 dual-stack sockets by default. When binding such a socket to 127.0.0.1, the kernel represents the address as ::ffff:127.0.0.1 (IPv4-mapped IPv6). macOS Seatbelt's "localhost" filter only matches 127.0.0.1 and ::1, not the IPv4-mapped variant, causing bind() to fail with EPERM. Seatbelt only supports two host values in IP filters: "localhost" and "*". Since we can't specify ::ffff:127.0.0.1 explicitly, change to (local ip "*:*"). This is safe because the (local ip) filter matches the LOCAL endpoint of connections — internet-bound traffic originates from non-loopback interfaces, so it remains blocked by the (deny default) rule. Fixes: https://github.com/anthropics/claude-code/issues/18545
This commit is contained in:
@@ -492,10 +492,17 @@ function generateSandboxProfile({
|
||||
profile.push('(allow network*)')
|
||||
} else {
|
||||
// Allow local binding if requested
|
||||
// Use "*:*" instead of "localhost:*" because modern runtimes (Java, etc.) create
|
||||
// IPv6 dual-stack sockets by default. When binding such a socket to 127.0.0.1,
|
||||
// the kernel represents it as ::ffff:127.0.0.1 (IPv4-mapped IPv6). Seatbelt's
|
||||
// "localhost" filter only matches 127.0.0.1 and ::1, NOT ::ffff:127.0.0.1.
|
||||
// Using (local ip "*:*") is safe because it only matches the LOCAL endpoint —
|
||||
// internet-bound connections originate from non-loopback interfaces, so they
|
||||
// remain blocked by (deny default).
|
||||
if (allowLocalBinding) {
|
||||
profile.push('(allow network-bind (local ip "localhost:*"))')
|
||||
profile.push('(allow network-inbound (local ip "localhost:*"))')
|
||||
profile.push('(allow network-outbound (local ip "localhost:*"))')
|
||||
profile.push('(allow network-bind (local ip "*:*"))')
|
||||
profile.push('(allow network-inbound (local ip "*:*"))')
|
||||
profile.push('(allow network-outbound (local ip "*:*"))')
|
||||
}
|
||||
// Unix domain sockets for local IPC (SSH agent, Docker, etc.)
|
||||
if (allowAllUnixSockets) {
|
||||
|
||||
Reference in New Issue
Block a user