fix: reject multicast and reserved egress addresses
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
This commit is contained in:
tegwick 2026-09-05 22:10:59 +02:00
parent d477c3b5d9
commit e45e3e6401
2 changed files with 9 additions and 4 deletions

View file

@ -25,7 +25,8 @@ def destinations(entries: list[str]) -> frozenset[str]:
def connect_public(host: str) -> socket.socket:
addresses = socket.getaddrinfo(host, 443, type=socket.SOCK_STREAM)
if not addresses or any(not ipaddress.ip_address(a[4][0]).is_global for a in addresses):
ips = [ipaddress.ip_address(a[4][0]) for a in addresses]
if not ips or any(not ip.is_global or ip.is_multicast or ip.is_reserved for ip in ips):
raise ValueError("non-public destination")
# Connect to the already checked numeric address; never resolve a second time.
for family, kind, proto, _, address in addresses:

View file

@ -24,7 +24,8 @@ def test_invalid_destination(entry):
@pytest.mark.parametrize(
"address", ["127.0.0.1", "10.0.0.1", "169.254.169.254", "::1", "::ffff:127.0.0.1"]
"address",
["127.0.0.1", "10.0.0.1", "169.254.169.254", "::1", "::ffff:127.0.0.1", "224.0.0.1", "ff02::1"],
)
def test_nonpublic_dns_refused(address):
with (
@ -106,10 +107,13 @@ def test_profile_cannot_expand_owner_allowlist(tmp_path):
def test_failed_broker_readiness_removes_egress():
from sandboxer.extensions.bwrap import BwrapExtension
ext = BwrapExtension()
handle = {"egress_pid": "123"}
with patch.object(ext, "_wait_ready", side_effect=RuntimeError("startup failed")), \
patch.object(ext, "teardown") as cleanup:
with (
patch.object(ext, "_wait_ready", side_effect=RuntimeError("startup failed")),
patch.object(ext, "teardown") as cleanup,
):
with pytest.raises(RuntimeError, match="startup failed"):
ext.wait_ready(handle)
cleanup.assert_called_once_with(handle)