diff --git a/resources/references/config-reference/server/apache.md b/resources/references/config-reference/server/apache.md index b40222374d..d0f6f91136 100644 --- a/resources/references/config-reference/server/apache.md +++ b/resources/references/config-reference/server/apache.md @@ -14,6 +14,13 @@ The document root must always point to the public folder, to ensure all function AllowOverride All Order allow,deny allow from all + + + Header set Content-Security-Policy "script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'" "expr=-f %{REQUEST_FILENAME} && %{REQUEST_URI} =~ m#^/(media|thumbnail)/.*[.](?i:html)$#" + + Header set Content-Security-Policy "script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'" + + ErrorLog ${APACHE_LOG_DIR}/shopware.error.log diff --git a/resources/references/config-reference/server/caddy.md b/resources/references/config-reference/server/caddy.md index 9db63a85b1..4ca6bb8f13 100644 --- a/resources/references/config-reference/server/caddy.md +++ b/resources/references/config-reference/server/caddy.md @@ -7,12 +7,12 @@ mydomain.com { Referrer-Policy no-referrer-when-downgrade } - @svg { + @staticDocuments { file - path *.svg + path_regexp staticDocuments (?i)([.]svg$|^/(media|thumbnail)/.*[.]html$) } - header @svg Content-Security-Policy "script-src 'none'" + header @staticDocuments Content-Security-Policy "script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'" @default { not path /theme/* /media/* /thumbnail/* /bundles/* /css/* /fonts/* /js/* /recovery/* /sitemap/* diff --git a/resources/references/config-reference/server/nginx.md b/resources/references/config-reference/server/nginx.md index a1521c4336..5b49327c8a 100644 --- a/resources/references/config-reference/server/nginx.md +++ b/resources/references/config-reference/server/nginx.md @@ -47,6 +47,14 @@ server { } } + # Stored HTML must not affect pages rendered by PHP. + location ~* ^/(media|thumbnail)/.*[.]html$ { + try_files $uri =404; + expires 1y; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + add_header Content-Security-Policy "script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'"; + } + location ~ ^/(theme|media|thumbnail|bundles|css|fonts|js|recovery|sitemap)/ { expires 1y; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; @@ -58,13 +66,13 @@ server { open_file_cache_errors off; location ~* ^.+\.svg { - add_header Content-Security-Policy "script-src 'none'"; + add_header Content-Security-Policy "script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'"; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; log_not_found off; } } - location ~* ^.+\.(?:css|cur|js|jpe?g|gif|ico|png|svg|webp|html|woff|woff2|xml)$ { + location ~* ^.+\.(?:css|cur|js|jpe?g|gif|ico|png|webp|html|woff|woff2|xml)$ { expires 1y; add_header Cache-Control "public, must-revalidate, proxy-revalidate"; @@ -85,7 +93,10 @@ server { } location ~* ^.+\.svg$ { - add_header Content-Security-Policy "script-src 'none'"; + try_files $uri /index.php$is_args$args; + expires 1y; + add_header Cache-Control "public, must-revalidate, proxy-revalidate"; + add_header Content-Security-Policy "script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'"; } location / { diff --git a/resources/references/security.md b/resources/references/security.md index 3f3b64b60f..0eda9adbf2 100644 --- a/resources/references/security.md +++ b/resources/references/security.md @@ -33,6 +33,24 @@ Captchas help to verify the user's humanity and prevent automated bots or script The default policies are configured over the `shopware.security.csp_templates` symfony container parameter and can be adjusted over the container configuration. +## XSS on stored assets + +Stored HTML and SVG files can execute scripts when opened directly in a browser. When these files share an origin with the shop, malicious content can cause cross-site scripting (XSS). Web servers and CDNs often serve stored assets without passing through Shopware, so the application's CSP does not protect these responses. + +Serve stored HTML and SVG assets with the following response header: + +```http +Content-Security-Policy: script-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none' +``` + +This policy blocks scripts, embedded documents, base URL overrides and form submissions while permitting images and styles. It must be present on the asset response, including when a cache serves the file. + +The provided [Apache](./config-reference/server/apache.md), [Nginx](./config-reference/server/nginx.md) and [Caddy](./config-reference/server/caddy.md) configurations include CSP protection for stored HTML and SVG. Update and deploy existing configurations to receive these protections. + +When using a [reverse proxy](../../guides/hosting/infrastructure/reverse-http-cache.md), ensure that it preserves the `Content-Security-Policy` header from the origin server, including on cached responses. Shopware's default Fastly and Varnish configurations preserve this header. + +If you serve static assets from a dedicated CDN using a different CDN URL, configure this response header manually in that CDN. Shopware's application and webserver configuration cannot enforce headers on responses served independently by the CDN. Ensure that your CDN includes this header when serving stored HTML and SVG files, including cached responses. A separate CDN URL does not replace CSP protection for active documents served from it. + ## File access Shopware 6 stores and processes a wide variety of files. This goes from product images or videos to generated documents such as invoices or delivery notes. This data should be stored securely, and backups should be generated regularly. For more information, refer to [File system](../../guides/hosting/infrastructure/filesystem)