From ad8f30cb09ea2295fc9163915d2171b74b261e32 Mon Sep 17 00:00:00 2001 From: fs Date: Fri, 13 Mar 2026 19:24:10 +0100 Subject: [PATCH] feat(security): add Content-Security-Policy headers with strict script-src Eliminate all inline scripts to enable script-src 'self' without 'unsafe-inline', providing strong XSS mitigation via CSP. Inline script removal: - login.phtml: replace inline APP_ASSET_BASE with data-asset-base attribute + app-boot.js (matching default.phtml pattern) - api-docs: extract SwaggerUI init to js/pages/admin-api-docs-index.js - docs: extract checkbox enablement to js/pages/admin-docs-index.js - language-switcher: replace onchange handler with data-auto-submit attribute + js/components/app-auto-submit.js event listener CSP policy (dev + prod nginx): default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'none'; manifest-src 'self' Co-Authored-By: Claude Opus 4.6 --- docker/nginx/default.conf | 1 + docker/nginx/prod.conf | 2 ++ pages/admin/api-docs/index(default).phtml | 25 ++----------------- pages/admin/docs/index(default).phtml | 8 +----- templates/login.phtml | 5 ++-- .../partials/app-language-switcher.phtml | 2 +- web/js/app-init.js | 1 + web/js/components/app-auto-submit.js | 12 +++++++++ web/js/pages/admin-api-docs-index.js | 16 ++++++++++++ web/js/pages/admin-docs-index.js | 3 +++ 10 files changed, 41 insertions(+), 34 deletions(-) create mode 100644 web/js/components/app-auto-submit.js create mode 100644 web/js/pages/admin-api-docs-index.js create mode 100644 web/js/pages/admin-docs-index.js diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf index ca71e9e..1cf386a 100644 --- a/docker/nginx/default.conf +++ b/docker/nginx/default.conf @@ -9,6 +9,7 @@ server { add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()" always; add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'none'; manifest-src 'self';" always; root /var/www/web; index index.php; diff --git a/docker/nginx/prod.conf b/docker/nginx/prod.conf index 26c7486..de3ab0a 100644 --- a/docker/nginx/prod.conf +++ b/docker/nginx/prod.conf @@ -7,6 +7,7 @@ server { add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()" always; add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'none'; manifest-src 'self'; upgrade-insecure-requests;" always; return 301 https://$host$request_uri; } @@ -30,6 +31,7 @@ server { add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=()" always; add_header X-Permitted-Cross-Domain-Policies "none" always; add_header Strict-Transport-Security "max-age=31536000" always; + add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; form-action 'self'; base-uri 'self'; frame-ancestors 'none'; manifest-src 'self'; upgrade-insecure-requests;" always; root /var/www/web; index index.php; diff --git a/pages/admin/api-docs/index(default).phtml b/pages/admin/api-docs/index(default).phtml index 743a2e0..758fd2e 100644 --- a/pages/admin/api-docs/index(default).phtml +++ b/pages/admin/api-docs/index(default).phtml @@ -8,29 +8,8 @@ require templatePath('partials/app-breadcrumb.phtml'); ?>
-
+
- + diff --git a/pages/admin/docs/index(default).phtml b/pages/admin/docs/index(default).phtml index 63cb26c..a1df697 100644 --- a/pages/admin/docs/index(default).phtml +++ b/pages/admin/docs/index(default).phtml @@ -70,10 +70,4 @@ - + diff --git a/templates/login.phtml b/templates/login.phtml index 3356437..550fa40 100644 --- a/templates/login.phtml +++ b/templates/login.phtml @@ -17,15 +17,14 @@ if ($bufferTitle !== '') { style="" > + - <?php e($pageTitle); ?> diff --git a/templates/partials/app-language-switcher.phtml b/templates/partials/app-language-switcher.phtml index 9abf713..f92c32f 100644 --- a/templates/partials/app-language-switcher.phtml +++ b/templates/partials/app-language-switcher.phtml @@ -44,7 +44,7 @@ $publicTarget = ltrim($publicTarget, '/');