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

A new setting, referer_blocklist (PIXA_REFERER_BLOCKLIST), lists hosts
written and matched as allowlist_hosts are, with the same matcher and the
same entry check; a bad entry aborts startup naming the setting and the
entry. Both image routes check the Referer first and answer 403 with the
JSON error, so a blocked request fetches nothing and is refused whether or
not the image is cached. No Referer, or one that does not parse as a URL
with a host, is served; README.md and config.example.yml say this makes the
list easy to get around. The CIDR-list entry reader is renamed listEntries
now that host lists use it too.

Model: opus-5-5
This commit is contained in:
2026-10-04 19:08:30 +00:00
parent b2c6bc91d0
commit c9a8b926db
7 changed files with 141 additions and 34 deletions
+11 -2
View File
@@ -27,7 +27,7 @@ The disk cache is now size-bounded with LRU eviction
# Next Step
P2: security: referer blacklist
P2: security: per-IP rate limiting on the image routes
# Completed Steps
@@ -47,6 +47,16 @@ P2: security: referer blacklist
for it, and the default `db_url` turns on WAL mode with
`_pragma=journal_mode(WAL)`. The old default's `_journal_mode=WAL` is not a
parameter the driver reads, so the database was never in WAL mode.
- 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 that is not a bare host
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
anything else is done for it, 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 `config.example.yml` say so. It does not apply to the login
and generator pages.
- 2026-10-04 `TestPeriodicReconciliationAdoptsFileThatAppearsAfterStartup`
only passes through a periodic pass (closes #189): it slept for three
eviction intervals before writing its file, and a startup pass still running
@@ -561,7 +571,6 @@ P2: security: referer blacklist
# Future Steps
- P2: security
- per-IP rate limiting on the image routes
- per-origin rate limiting
- P2: HTTP response handling
- Last-Modified headers