diff --git a/internal/imgcache/service.go b/internal/imgcache/service.go index c7706c5..01f0db3 100644 --- a/internal/imgcache/service.go +++ b/internal/imgcache/service.go @@ -7,9 +7,9 @@ import ( "fmt" "io" "log/slog" - "net" "net/url" "runtime/debug" + "strings" "time" "github.com/dustin/go-humanize" @@ -220,11 +220,13 @@ func (s *Service) ValidateRequest(req *ImageRequest) error { } // An allowlist entry names no port, so a host followed by ":", with or - // without a port, needs a signature. This is checked here and not in - // allowlist.IsAllowed, which also matches referer_blocklist, where a - // Referer must be blocked whatever its port. - _, _, splitErr := net.SplitHostPort(parsedURL.Host) - hostHasPort := splitErr == nil + // without a port, needs a signature. The port is read from the parsed + // URL, as the fetcher reads it: in an IPv6 address written without + // brackets, such as 2001:db8::1:8443, it is what follows the last ":". + // This is checked here and not in allowlist.IsAllowed, which also matches + // referer_blocklist, where a Referer must be blocked whatever its port. + hostHasPort := parsedURL.Port() != "" || + strings.HasSuffix(parsedURL.Host, ":") if !hostHasPort && s.allowlist.IsAllowed(parsedURL) { return nil