From 0de47d429ef838b517c5eb9fd82d38f4049c17a7 Mon Sep 17 00:00:00 2001 From: nisbet-hubbard <87453615+nisbet-hubbard@users.noreply.github.com> Date: Sat, 19 Jul 2025 14:00:13 +0800 Subject: [PATCH 1/4] Remove deprecated X-XSS-Protection header See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-XSS-Protection --- docs/example-advanced.nginx.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/example-advanced.nginx.conf b/docs/example-advanced.nginx.conf index 78d00d81b..35c9b4087 100644 --- a/docs/example-advanced.nginx.conf +++ b/docs/example-advanced.nginx.conf @@ -92,7 +92,6 @@ server { # OnlyOffice fonts may be loaded from both domains if ($uri ~ ^/common/onlyoffice/.*/fonts/) { set $allowed_origins "*"; } - add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options nosniff; add_header Access-Control-Allow-Origin "${allowed_origins}"; add_header Access-Control-Allow-Credentials true; @@ -276,7 +275,6 @@ server { proxy_hide_header 'X-Content-Type-Options'; proxy_hide_header 'Access-Control-Allow-Origin'; proxy_hide_header 'Permissions-Policy'; - proxy_hide_header 'X-XSS-Protection'; proxy_hide_header 'Cross-Origin-Resource-Policy'; proxy_hide_header 'Cross-Origin-Embedder-Policy'; proxy_pass http://localhost:3000; From 10150d1969a46a6602b821c517925b60c3659f62 Mon Sep 17 00:00:00 2001 From: nisbet-hubbard <87453615+nisbet-hubbard@users.noreply.github.com> Date: Sat, 19 Jul 2025 14:16:56 +0800 Subject: [PATCH 2/4] Remove deprecated interest-cohort header The FLoC trials ended in 2021 and got replaced by Topics API. See https://developer.chrome.com/origintrials/#/view_trial/213920982300098561 and https://blog.google/products/chrome/get-know-new-topics-api-privacy-sandbox/ --- docs/example-advanced.nginx.conf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/example-advanced.nginx.conf b/docs/example-advanced.nginx.conf index 35c9b4087..fbb01a945 100644 --- a/docs/example-advanced.nginx.conf +++ b/docs/example-advanced.nginx.conf @@ -97,9 +97,6 @@ server { add_header Access-Control-Allow-Credentials true; # add_header X-Frame-Options "SAMEORIGIN"; - # Opt out of Google's FLoC Network - add_header Permissions-Policy interest-cohort=(); - # Enable SharedArrayBuffer in Firefox (for .xlsx export) add_header Cross-Origin-Resource-Policy cross-origin; add_header Cross-Origin-Embedder-Policy require-corp; @@ -274,7 +271,6 @@ server { # so we hide them proxy_hide_header 'X-Content-Type-Options'; proxy_hide_header 'Access-Control-Allow-Origin'; - proxy_hide_header 'Permissions-Policy'; proxy_hide_header 'Cross-Origin-Resource-Policy'; proxy_hide_header 'Cross-Origin-Embedder-Policy'; proxy_pass http://localhost:3000; 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 3/4] 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; + } } From 45d325755f47eb1b7a74aeb37d80e665d00dcc46 Mon Sep 17 00:00:00 2001 From: nisbet-hubbard <87453615+nisbet-hubbard@users.noreply.github.com> Date: Sat, 19 Jul 2025 20:53:26 +0800 Subject: [PATCH 4/4] Remove check for deprecated FLoC opt-out --- www/checkup/main.js | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/www/checkup/main.js b/www/checkup/main.js index ff6fe231e..daf45fccc 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -448,38 +448,6 @@ define([ }); } - assert(function (cb, msg) { - setWarningClass(msg); - - var printMessage = function (value) { - msg.appendChild(h('span', [ - "This instance hasn't opted out of participation in Google's ", - code('FLoC'), - " targeted advertizing network. ", - - "This can be done by setting a ", - code('permissions-policy'), - " HTTP header with a value of ", - code('"interest-cohort=()"'), - " in the configuration of its reverse proxy instead of the current value (", - code(value), - "). See the provided NGINX configuration file for an example. ", - - h('p', [ - link("https://www.eff.org/deeplinks/2021/04/am-i-floced-launch", 'Learn more'), - ]), - ])); - }; - - Tools.common_xhr('/', function (xhr) { - var header = xhr.getResponseHeader('permissions-policy') || ''; - var rules = header.split(','); - if (rules.includes('interest-cohort=()')) { return void cb(true); } - printMessage(JSON.stringify(header)); - cb(header); - }); - }); - assert(function (cb, msg) { msg.appendChild(h('span', [ code('/api/broadcast'),