From c7f7941de273be760d1585ef8374edeea68c12ea Mon Sep 17 00:00:00 2001 From: nisbet-hubbard <87453615+nisbet-hubbard@users.noreply.github.com> Date: Sat, 19 Jul 2025 20:46:07 +0800 Subject: [PATCH] Restrict Content-Security-Policy to static assets --- docs/example-advanced.nginx.conf | 92 ++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/docs/example-advanced.nginx.conf b/docs/example-advanced.nginx.conf index fbb01a945..33dc6eb92 100644 --- a/docs/example-advanced.nginx.conf +++ b/docs/example-advanced.nginx.conf @@ -181,9 +181,6 @@ server { set $scriptSrc "'self' 'unsafe-eval' 'unsafe-inline' resource: https://${main_domain}"; } - # Finally, set all the rules you composed above. - add_header Content-Security-Policy "default-src 'none'; child-src $childSrc; worker-src $workerSrc; media-src $mediaSrc; style-src $styleSrc; script-src $scriptSrc; connect-src $connectSrc; font-src $fontSrc; img-src $imgSrc; frame-src $frameSrc; frame-ancestors $frameAncestors"; - # Add support for .mjs files used by pdfjs types { application/javascript mjs; @@ -207,16 +204,78 @@ server { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; + + # HSTS (ngx_http_headers_module is required) (63072000 seconds) + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; + + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin "${allowed_origins}"; + add_header Access-Control-Allow-Credentials true; + # add_header X-Frame-Options "SAMEORIGIN"; + + # Enable SharedArrayBuffer in Firefox (for .xlsx export) + add_header Cross-Origin-Resource-Policy cross-origin always; + add_header Cross-Origin-Embedder-Policy require-corp always; + add_header Referrer-Policy same-origin; + + # Will not set any header if it is emptystring + add_header Cache-Control $cacheControl; + + # Set all the rules you composed above. + add_header Content-Security-Policy "default-src 'none'; child-src $childSrc; worker-src $workerSrc; media-src $mediaSrc; style-src $styleSrc; script-src $scriptSrc; connect-src $connectSrc; font-src $fontSrc; img-src $imgSrc; frame-src $frameSrc; frame-ancestors $frameAncestors" always; } location ^~ /customize.dist/ { # This is needed in order to prevent infinite recursion between /customize/ and the root + + if ($uri ~ ^/.*\.html) { + # HSTS (ngx_http_headers_module is required) (63072000 seconds) + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; + + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin "${allowed_origins}"; + add_header Access-Control-Allow-Credentials true; + # add_header X-Frame-Options "SAMEORIGIN"; + + # Enable SharedArrayBuffer in Firefox (for .xlsx export) + add_header Cross-Origin-Resource-Policy cross-origin always; + add_header Cross-Origin-Embedder-Policy require-corp always; + add_header Referrer-Policy same-origin; + + # Will not set any header if it is emptystring + add_header Cache-Control $cacheControl; + + # Set all the rules you composed above. + add_header Content-Security-Policy "default-src 'none'; child-src $childSrc; worker-src $workerSrc; media-src $mediaSrc; style-src $styleSrc; script-src $scriptSrc; connect-src $connectSrc; font-src $fontSrc; img-src $imgSrc; frame-src $frameSrc; frame-ancestors $frameAncestors" always; + } } # try to load customizeable content via /customize/ and fall back to the default content # located at /customize.dist/ # This is what allows you to override behaviour. location ^~ /customize/ { rewrite ^/customize/(.*)$ $1 break; + + if ($uri ~ ^/.*\.html) { + # HSTS (ngx_http_headers_module is required) (63072000 seconds) + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; + + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin "${allowed_origins}"; + add_header Access-Control-Allow-Credentials true; + # add_header X-Frame-Options "SAMEORIGIN"; + + # Enable SharedArrayBuffer in Firefox (for .xlsx export) + add_header Cross-Origin-Resource-Policy cross-origin always; + add_header Cross-Origin-Embedder-Policy require-corp always; + add_header Referrer-Policy same-origin; + + # Will not set any header if it is emptystring + add_header Cache-Control $cacheControl; + + # Set all the rules you composed above. + add_header Content-Security-Policy "default-src 'none'; child-src $childSrc; worker-src $workerSrc; media-src $mediaSrc; style-src $styleSrc; script-src $scriptSrc; connect-src $connectSrc; font-src $fontSrc; img-src $imgSrc; frame-src $frameSrc; frame-ancestors $frameAncestors" always; + } + try_files /customize/$uri /customize.dist/$uri; } @@ -284,5 +343,30 @@ server { } # Finally, serve anything the above exceptions don't govern. - try_files /customize/www/$uri /customize/www/$uri/index.html /src/$uri /www/$uri /www/$uri/index.html /src/$uri /customize/$uri; + location ~* \.(css|js|mjs|png|svg|gif|ico|woff|woff2|eot|otf|ttf|cur|map)$ { + try_files /customize/www/$uri /customize/www/$uri/index.html /src/$uri /www/$uri /www/$uri/index.html /src/$uri /customize/$uri; + } + + location / { + # HSTS (ngx_http_headers_module is required) (63072000 seconds) + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; + + add_header X-Content-Type-Options nosniff; + add_header Access-Control-Allow-Origin "${allowed_origins}"; + add_header Access-Control-Allow-Credentials true; + # add_header X-Frame-Options "SAMEORIGIN"; + + # Enable SharedArrayBuffer in Firefox (for .xlsx export) + add_header Cross-Origin-Resource-Policy cross-origin always; + add_header Cross-Origin-Embedder-Policy require-corp always; + add_header Referrer-Policy same-origin; + + # Will not set any header if it is emptystring + add_header Cache-Control $cacheControl; + + # Set all the rules you composed above. + add_header Content-Security-Policy "default-src 'none'; child-src $childSrc; worker-src $workerSrc; media-src $mediaSrc; style-src $styleSrc; script-src $scriptSrc; connect-src $connectSrc; font-src $fontSrc; img-src $imgSrc; frame-src $frameSrc; frame-ancestors $frameAncestors" always; + + try_files /customize/www/$uri /customize/www/$uri/index.html /src/$uri /www/$uri /www/$uri/index.html /src/$uri /customize/$uri; + } }