Background security review (MEDIUM). is_safe_public_url (tinyagentos/userspace/url_guard.py) resolves + validates a hostname's IPs, but install_app then re-resolves the hostname when httpx connects, leaving a DNS-rebinding / TOCTOU window where the connected IP can differ from the validated one (and bounce to an internal address).
Fix
Resolve once in is_safe_public_url, return the validated IP(s), and pin the httpx connection to that IP (a custom transport / pinned resolver) while preserving the original Host header and SNI for TLS.
Scheduling
This lives in install_app's source_url fetch, which the P2 distribution phase rebuilds into a proper download broker (signed-bundle fetch + sha256 + signature + min_os verification). The DNS-pinned fetch belongs there, so it is folded into P2 rather than fixed in isolation, and to avoid colliding with the in-flight P3b branch that edits the same install_app function.
Note: is_safe_public_url already blocks the obvious case (private / loopback / reserved IPs at check time); this closes the rebinding residual. Not yet on master (master is gated), so not shipping.
Part of #89 (P2 download broker).
Background security review (MEDIUM). is_safe_public_url (tinyagentos/userspace/url_guard.py) resolves + validates a hostname's IPs, but install_app then re-resolves the hostname when httpx connects, leaving a DNS-rebinding / TOCTOU window where the connected IP can differ from the validated one (and bounce to an internal address).
Fix
Resolve once in is_safe_public_url, return the validated IP(s), and pin the httpx connection to that IP (a custom transport / pinned resolver) while preserving the original Host header and SNI for TLS.
Scheduling
This lives in install_app's source_url fetch, which the P2 distribution phase rebuilds into a proper download broker (signed-bundle fetch + sha256 + signature + min_os verification). The DNS-pinned fetch belongs there, so it is folded into P2 rather than fixed in isolation, and to avoid colliding with the in-flight P3b branch that edits the same install_app function.
Note: is_safe_public_url already blocks the obvious case (private / loopback / reserved IPs at check time); this closes the rebinding residual. Not yet on master (master is gated), so not shipping.
Part of #89 (P2 download broker).