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, configs/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; the example config says the list does not cover the login and generator pages. Model: opus-5-5
This commit is contained in:
+19
-21
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user