Fixed apache CSP policy to exclude index.php served requests

When using mod_php the setifempty directive does not work , which blocks assets from loading. Fixes issue #1423
This commit is contained in:
Jan Böhmer 2026-07-17 00:05:27 +02:00
parent 90a5ab74ff
commit 1b740ed674

View file

@ -120,12 +120,23 @@ DirectoryIndex index.php
</IfModule> </IfModule>
<IfModule mod_headers.c> <IfModule mod_headers.c>
# Set a strict CSP for all static assets not handled by PHP. # Set a strict CSP for everything Apache serves, except the front controller (index.php),
# PHP responses already carry their own CSP via NelmioSecurityBundle, so setifempty leaves those untouched. # whose response CSP is set by NelmioSecurityBundle in PHP. Excluding it via a negative
Header always setifempty Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; sandbox;" # FilesMatch (rather than a blanket rule relying on "setifempty" to skip PHP responses)
Header always setifempty X-Content-Type-Options "nosniff" # avoids depending on mod_headers detecting the PHP-set header at the right time: on a
# real Apache 2.4/mod_php install, "setifempty" did not reliably suppress the static policy,
# so BOTH Content-Security-Policy headers ended up on the same PHP response, and browsers
# enforce the intersection of all CSP headers on a response - so "script-src 'none';
# sandbox" silently disabled all scripts/styles site-wide. mod_rewrite's internal redirect
# to index.php re-runs directory-scoped matching against the new target, so this FilesMatch
# reliably excludes it regardless of the originally requested URL.
<FilesMatch "^(?!index\.php$).+$">
Header always set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; sandbox;"
Header always set X-Content-Type-Options "nosniff"
</FilesMatch>
# SVG files get a slightly different CSP because they can embed resources and must not be framed. # SVG files get a slightly different CSP because they can embed resources and must not be framed.
# (Declared after the general rule above so its more specific "set" wins for SVG files.)
<FilesMatch "\.(svg|svg\.gz|svg\.br)$"> <FilesMatch "\.(svg|svg\.gz|svg\.br)$">
Header always set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; sandbox;" Header always set Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; sandbox;"
</FilesMatch> </FilesMatch>