Tracking a known limitation flagged in review of #631.
The gateway validates cast/clip target URLs by resolving the hostname and rejecting private/loopback/link-local/CGNAT ranges (resolveTargetAllowed in examples/web-capture/cmd/gateway/capture.go). The check resolves DNS once at request time, but the actual fetch happens later inside the Servo pipeline, which performs its own resolution — a rebinding DNS server can return a public IP to the gateway's check and a private IP to Servo, reaching internal services.
Closing the gap properly means pinning the validated IP through the fetch (or running Servo in a network-isolated namespace / egress-filtered environment), which is out of scope for the example gateway itself. Documenting mitigation options (egress firewall, isolated network for the skit backend) would also help.
Tracking a known limitation flagged in review of #631.
The gateway validates cast/clip target URLs by resolving the hostname and rejecting private/loopback/link-local/CGNAT ranges (
resolveTargetAllowedinexamples/web-capture/cmd/gateway/capture.go). The check resolves DNS once at request time, but the actual fetch happens later inside the Servo pipeline, which performs its own resolution — a rebinding DNS server can return a public IP to the gateway's check and a private IP to Servo, reaching internal services.Closing the gap properly means pinning the validated IP through the fetch (or running Servo in a network-isolated namespace / egress-filtered environment), which is out of scope for the example gateway itself. Documenting mitigation options (egress firewall, isolated network for the skit backend) would also help.