Refuse image requests whose Referer is on referer_blocklist (closes #90)
check / check (push) Failing after 2s

A new setting, referer_blocklist (PIXA_REFERER_BLOCKLIST), lists hosts
whose pages may not show pixa's images. Entries are written and matched
as allowlist_hosts are, with the same matcher. Both image routes check
the Referer before the signature, the cache and the upstream fetch, and
answer 403 with the JSON error, so a blocked request costs nothing and
is refused whether or not the image is cached. No Referer, or one that
does not parse, is served; README.md says this makes the list easy to
get around. An entry of either host list that is not a host name
(letters, digits, hyphens, underscores, dots, at most one leading dot)
or an IP address now aborts startup naming the setting and the entry.

Model: opus-5-5
This commit was merged in pull request #197.
This commit is contained in:
2026-10-04 22:24:50 +02:00
parent 8568c17d1b
commit 8314099abd
11 changed files with 559 additions and 48 deletions
+12
View File
@@ -46,6 +46,8 @@ signing_key: "CHANGE_ME_generate_with_openssl_rand_base64_32"
# Hosts that don't require signatures (default: none)
# Use "." prefix for wildcard subdomain matching (e.g., ".example.com" matches "cdn.example.com")
# An entry that is neither a host name nor an IP address (IPv6 without
# brackets), such as one with a port or a "*." wildcard, aborts startup.
allowlist_hosts:
- s3.sneak.cloud
- static.sneak.cloud
@@ -53,6 +55,16 @@ allowlist_hosts:
- github.com
- user-images.githubusercontent.com
# Hosts whose pages may not show pixa's images, written as for
# allowlist_hosts. A request to /v1/image/ or /v1/e/ whose Referer header
# names one of them is answered 403 before anything is fetched, even when
# the image is cached. A request with no Referer, or one that does not
# parse, is served, so a site whose pages send no Referer is not stopped.
# The login and generator pages are not covered. (default: none)
# referer_blocklist:
# - leech.example
# - .hotlinker.example
# Additional CIDR ranges to refuse when fetching upstream, extending the
# SSRF protection. These are added to the always-enforced built-in ranges
# (loopback, RFC 1918 private, link-local, CGNAT, benchmark, NAT64, and