Files
pixa/internal/imgcache/whitelist.go
user 215ddb7f72 fix: remove suffix matching from host whitelist
Whitelist entries now support exact host matches only. Leading dots
in patterns are stripped for backwards compatibility (.example.com
becomes an exact match for example.com). Suffix matching that would
match arbitrary subdomains is no longer supported.

Closes #27
2026-03-15 11:18:25 -07:00

70 lines
1.7 KiB
Go

package imgcache
import (
"net/url"
"strings"
)
// HostWhitelist implements the Whitelist interface for checking allowed source hosts.
// Only exact host matches are supported. Leading dots in patterns are stripped
// (e.g. ".example.com" becomes an exact match for "example.com").
type HostWhitelist struct {
// hosts contains hosts that must match exactly (e.g., "cdn.example.com")
hosts map[string]struct{}
}
// NewHostWhitelist creates a whitelist from a list of host patterns.
// All patterns are treated as exact matches. Leading dots are stripped
// for backwards compatibility (e.g. ".example.com" matches "example.com" only).
func NewHostWhitelist(patterns []string) *HostWhitelist {
w := &HostWhitelist{
hosts: make(map[string]struct{}),
}
for _, pattern := range patterns {
pattern = strings.ToLower(strings.TrimSpace(pattern))
if pattern == "" {
continue
}
// Strip leading dot — suffix matching is not supported.
// ".example.com" is treated as exact match for "example.com".
pattern = strings.TrimPrefix(pattern, ".")
if pattern == "" {
continue
}
w.hosts[pattern] = struct{}{}
}
return w
}
// IsWhitelisted checks if a URL's host is in the whitelist.
// Only exact host matches are supported.
func (w *HostWhitelist) IsWhitelisted(u *url.URL) bool {
if u == nil {
return false
}
host := strings.ToLower(u.Hostname())
if host == "" {
return false
}
_, ok := w.hosts[host]
return ok
}
// IsEmpty returns true if the whitelist has no entries.
func (w *HostWhitelist) IsEmpty() bool {
return len(w.hosts) == 0
}
// Count returns the total number of whitelist entries.
func (w *HostWhitelist) Count() int {
return len(w.hosts)
}