mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 16:46:17 +00:00
CodeQL re-fired three new go/request-forgery alerts (#134/135/136) on the lines my previous validateZcBaseURL refactor introduced. The previous validator accepted hostname-style hosts unchanged, so even though the IP-class check ran when applicable, u.String() at the call sites still emitted the original tainted host into the request URL — which is exactly what CodeQL traces. Tighten validateZcBaseURL to: * require the host to parse as a literal IP — DNS / mDNS hostnames are rejected (with a clear error explaining the caller should resolve to a private IP first); doing the lookup inside the validator would re-introduce the SSRF surface CodeQL is flagging, because malicious DNS could point a *.local name at a public host between the lookup and the request. * require that IP to be loopback / RFC1918 private / IPv4-or-IPv6 link-local. Anything else (global IPs in either family) is refused. * rebuild the returned *url.URL from validated components — scheme (already checked), the validated IP literal joined with the original port, and the original path. Pre-existing query/fragment are stripped so callers attach their own ?action= cleanly. CodeQL recognises this fresh-construction pattern as taint sanitisation. In practice this matches what SoundTouch speakers actually announce: IP-based zeroconf URLs at port 8200 against an LAN address. The existing PushCredentials_FullRoundTrip and FallbackOnGetInfoFailure tests already exercise the loopback path through httptest.NewServer and pass unchanged. Adds TestValidateZcBaseURL covering 17 inputs — 9 accept (loopback, private 10/172/192, link-local v4, IPv6 loopback, IPv6 link-local, strips query) and 8 reject (public IPv4, public IPv6, hostname, plain hostname, ftp/file schemes, empty host, unparseable) — to lock the new contract in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>