Refuse image requests whose Referer is on referer_blocklist (closes #90) #197

Merged
clawbot merged 7 commits from issue-90-referer-blocklist into next 2026-10-04 22:24:50 +02:00
3 changed files with 17 additions and 16 deletions
Showing only changes of commit 6259832fb3 - Show all commits
+3 -3
View File
@@ -396,9 +396,9 @@ and the URL is
`images.example.com`, and `example.com`
An IP address is matched exactly; write an IPv6 address without brackets. An
entry that is neither a host name (letters, digits, hyphens and dots, with at
most one leading dot) nor an IP address, such as one with a port or a `*.`
wildcard, aborts startup.
entry that is neither a host name (letters, digits, hyphens, underscores and
dots, with at most one leading dot) nor an IP address, such as one with a port
or a `*.` wildcard, aborts startup.
### Configuration
+9 -9
View File
@@ -34,15 +34,15 @@ P2: security: per-IP rate limiting on the image routes
- 2026-10-04 referer blocklist (closes #90): `referer_blocklist`
(`PIXA_REFERER_BLOCKLIST`) lists hosts, written and matched as for
`allowlist_hosts` with the same matcher; an entry of either list that is
neither a host name (letters, digits, hyphens and dots, with at most one
leading dot) nor an IP address, such as one with a port or a `*.` wildcard,
aborts startup naming the setting and the entry. Both image routes refuse a
request whose `Referer` names a listed host with 403 and a JSON error before
the signature, the cache and the upstream fetch, so it fetches nothing and is
refused whether or not the image is cached. A request with no `Referer`, or
one that does not parse as a URL with a host, is served, so the list is easily
got around; `README.md` and `configs/config.example.yml` say so. It does not
apply to the login and generator pages.
neither a host name (letters, digits, hyphens, underscores and dots, with at
most one leading dot) nor an IP address, such as one with a port or a `*.`
wildcard, aborts startup naming the setting and the entry. Both image routes
refuse a request whose `Referer` names a listed host with 403 and a JSON error
before the signature, the cache and the upstream fetch, so it fetches nothing
and is refused whether or not the image is cached. A request with no
`Referer`, or one that does not parse as a URL with a host, is served, so the
list is easily got around; `README.md` and `configs/config.example.yml` say
so. It does not apply to the login and generator pages.
- 2026-10-04 fewer files in the repository root (closes #97):
`config.example.yml` moved unchanged to `configs/config.example.yml`, and
`README.md`, the comments in `internal/config/config.go` and the startup error
+5 -4
View File
@@ -742,14 +742,15 @@ 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.-]*$`)
// hostNamePattern matches a host name: letters, digits, hyphens, underscores
// 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 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.
// a URL, a port or a "*." wildcard, can never match a host name that resolves,
// 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 {