Refuse host entries that are not a host name or an IP address
check / check (push) Failing after 2s

An entry of allowlist_hosts or referer_blocklist that is neither a host
name (letters, digits, hyphens and dots, with at most one leading dot)
nor an IP address now aborts startup naming the setting and the entry,
so a `*.` wildcard or a port no longer loads and silently matches
nothing. README.md, config.example.yml and the TODO.md entry now say the
Referer check comes before the signature, the cache and the upstream
fetch, since maintenance mode answers first; config.example.yml says
the list does not cover the login and generator pages.

Model: opus-5-5
This commit is contained in:
2026-10-04 19:04:34 +00:00
parent a31dbcb70a
commit b3e744a744
4 changed files with 51 additions and 42 deletions
+19 -21
View File
@@ -11,6 +11,7 @@ import (
"net/url"
"os"
"path/filepath"
"regexp"
"runtime"
"sort"
"strconv"
@@ -98,12 +99,11 @@ var (
"value is null; omit the key entirely to use the default")
errValuesNull = errors.New(
"value is null; omit a key entirely to use its default")
errNotBareHostname = errors.New(
"must be a bare hostname without scheme, path, or whitespace")
errNoHostnameLabels = errors.New("contains no hostname labels")
errNotADuration = errors.New("not a duration such as 30s or 2m")
errMustBePositive = errors.New("must be positive")
errNotAnOrigin = errors.New(
errNotAHost = errors.New("must be a host name such as " +
"cdn.example.com or .example.com, or an IP address")
errNotADuration = errors.New("not a duration such as 30s or 2m")
errMustBePositive = errors.New("must be positive")
errNotAnOrigin = errors.New(
`not "*" or an origin such as https://example.com`)
)
@@ -742,25 +742,23 @@ func (c *Config) validateConcurrencyLimits() error {
return nil
}
// hostNamePattern matches a host name: letters, digits, hyphens and dots,
// optionally after one leading dot.
var hostNamePattern = regexp.MustCompile(`^\.?[A-Za-z0-9-][A-Za-z0-9.-]*$`)
// validateHostPattern checks that an entry of the named key, allowlist_hosts
// or referer_blocklist, is a bare hostname, optionally with a leading dot for
// suffix matching. URLs, paths, and whitespace indicate a misconfigured entry.
// An entry with no hostname labels (such as ".") is rejected: the allowlist
// matcher treats a leading dot as a suffix pattern, so a bare "." would match
// any host written in FQDN trailing-dot form, and in allowlist_hosts
// effectively disable URL signing.
// or referer_blocklist, is an IP address or a host name, the host name
// optionally with one leading dot for suffix matching. Anything else, such as
// a URL, a port or a "*." wildcard, can never match a host, so it is refused.
// So is "." alone: the allowlist matcher would match it against any host
// written with a trailing dot, which in allowlist_hosts disables URL signing.
func validateHostPattern(key, host string) error {
if strings.Contains(host, "://") || strings.ContainsAny(host, "/ \t") {
return fmt.Errorf("%s: entry %q %w",
settingName(key), host, errNotBareHostname)
_, err := netip.ParseAddr(host)
if err == nil || hostNamePattern.MatchString(host) {
return nil
}
if strings.Trim(host, ".") == "" {
return fmt.Errorf("%s: entry %q %w",
settingName(key), host, errNoHostnameLabels)
}
return nil
return fmt.Errorf("%s: entry %q %w", settingName(key), host, errNotAHost)
}
// loadConfigFile loads configuration from the PIXA_CONFIG_PATH env var