Serve uploaded SVGs under their CSP, and identify the image fetcher
The Content-Security-Policy meant for stored SVGs never applied: in Caddy a `*` in the middle of a path does not cross a `/`, so `path /storage/*.svg` only matched files directly under /storage, and every upload lives in a directory below it. Two matchers, which Caddy ANDs, cover any depth. RemoteImage fetched with Guzzle's anonymous default User-Agent, which Wikimedia answers with 403. It now sends `<app>/1.0 (+<app url>; media fetcher)`, the identification such hosts ask of automated clients. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,15 @@
|
||||
# second line: opened directly rather than through an <img>, an SVG is a
|
||||
# document, and nothing stored here has any business running script or
|
||||
# loading anything from elsewhere.
|
||||
@svg path /storage/*.svg
|
||||
#
|
||||
# Two matchers, which Caddy ANDs, rather than `path /storage/*.svg`: a `*`
|
||||
# in the middle of a path does not cross a `/`, so that pattern only ever
|
||||
# matched files directly under /storage — and every upload is a directory
|
||||
# below it.
|
||||
@svg {
|
||||
path /storage/*
|
||||
path_regexp (?i)\.svg$
|
||||
}
|
||||
header @svg Content-Security-Policy "default-src 'none'; style-src 'unsafe-inline'; img-src data:"
|
||||
|
||||
# The frontend is a separate application on another origin.
|
||||
|
||||
Reference in New Issue
Block a user