openvibers/openvibe.sites Commits
Sites vhosts: security headers on every response again
Changes
@@@ -317,8 +317,15 @@ a:first-child{background:var(--site);border-color:var(--site);color:#0b0d10}}/** nginx vhost: static root, wildcard cert, www → apex, long cache for the immutable bits, real 404s. */++const SECURITY_HEADERS = [++ 'add_header X-Content-Type-Options nosniff always;',++ 'add_header X-Frame-Options SAMEORIGIN always;',++ 'add_header Referrer-Policy strict-origin-when-cross-origin always;',++ 'add_header Strict-Transport-Security "max-age=31536000" always;',++];function vhost(site) {const d = site.domain;++ const sec = SECURITY_HEADERS.join('\n ');// Subdomains of a zone (e.g. events.openvibe.network) use the zone's wildcard cert and have no www.const cert = site.zone || d;const www = site.zone ? '' : `@@@ -355,18 +362,32 @@ server {access_log /var/log/nginx/${d}.access.log;error_log /var/log/nginx/${d}.error.log;-- add_header X-Content-Type-Options nosniff always;-- add_header X-Frame-Options SAMEORIGIN always;-- add_header Referrer-Policy strict-origin-when-cross-origin always;-- add_header Strict-Transport-Security "max-age=31536000" always;++ ${SECURITY_HEADERS.join('\n ')}gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ ${sec}++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ ${sec}++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ ${sec}++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ ${sec}++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -374,6 +395,7 @@ server {location / {add_header Cache-Control "public, max-age=600";++ ${sec}try_files $uri $uri.html $uri/ =404;}@@@ -29,10 +29,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -40,6 +69,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -29,10 +29,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -40,6 +69,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -29,10 +29,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -40,6 +69,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -29,10 +29,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -40,6 +69,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -39,10 +39,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -50,6 +79,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -29,10 +29,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -40,6 +69,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -29,10 +29,39 @@ server {gzip on;gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;-- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }-- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }-- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }-- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }++ # An add_header inside a location replaces the server's list (nginx does not merge them), so every++ # location that sets its own header repeats the security headers.++ location = /robots.txt {++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /sitemap.xml {++ types { application/xml xml; }++ add_header Cache-Control "public, max-age=3600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /manifest.webmanifest {++ types { application/manifest+json webmanifest; }++ add_header Cache-Control "public, max-age=86400";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }++ location = /status.json {++ add_header Cache-Control "public, max-age=600";++ add_header Access-Control-Allow-Origin "*";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;++ }# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.error_page 404 /404.html;@@@ -40,6 +69,10 @@ server {location / {add_header Cache-Control "public, max-age=600";++ add_header X-Content-Type-Options nosniff always;++ add_header X-Frame-Options SAMEORIGIN always;++ add_header Referrer-Policy strict-origin-when-cross-origin always;++ add_header Strict-Transport-Security "max-age=31536000" always;try_files $uri $uri.html $uri/ =404;}@@@ -60,6 +60,14 @@ for (const site of catalog.sites) {assert.ok(conf.includes('error_page 404 /404.html;'), `${d}: vhost answers 404 with /404.html`);assert.ok(conf.includes('try_files $uri $uri.html $uri/ =404;'), `${d}: vhost try_files ends in =404`);assert.doesNotMatch(conf, /try_files[^;]*\/index\.html;/, `${d}: vhost never falls back to the front page`);++ // nginx drops the server-level add_header list in any location with its own add_header: each such++ // location must repeat the security headers (they were missing from every Sites response until 2026-09-24).++ for (const m of conf.matchAll(/location [^{]*\{((?:[^{}]|\{[^{}]*\})*)\}/g)) {++ if (!/add_header/.test(m[1])) continue;++ for (const h of ['X-Content-Type-Options', 'X-Frame-Options', 'Referrer-Policy', 'Strict-Transport-Security']) {++ assert.ok(m[1].includes(`add_header ${h} `), `${d}: ${m[0].split('{')[0].trim()} repeats ${h}`);++ }++ }}// Labels come from facts (facts.json: each repository's STATUS.json + the Network registry), never a
@@ -317,8 +317,15 @@ a:first-child{background:var(--site);border-color:var(--site);color:#0b0d10}
@@ -317,8 +317,15 @@ a:first-child{background:var(--site);border-color:var(--site);color:#0b0d10}
}
}
/** nginx vhost: static root, wildcard cert, www → apex, long cache for the immutable bits, real 404s. */
/** nginx vhost: static root, wildcard cert, www → apex, long cache for the immutable bits, real 404s. */
+const SECURITY_HEADERS = [
+ 'add_header X-Content-Type-Options nosniff always;',
+ 'add_header X-Frame-Options SAMEORIGIN always;',
+ 'add_header Referrer-Policy strict-origin-when-cross-origin always;',
+ 'add_header Strict-Transport-Security "max-age=31536000" always;',
+];
function vhost(site) {
function vhost(site) {
const d = site.domain;
const d = site.domain;
+ const sec = SECURITY_HEADERS.join('\n ');
// Subdomains of a zone (e.g. events.openvibe.network) use the zone's wildcard cert and have no www.
// Subdomains of a zone (e.g. events.openvibe.network) use the zone's wildcard cert and have no www.
const cert = site.zone || d;
const cert = site.zone || d;
const www = site.zone ? '' : `
const www = site.zone ? '' : `
@@ -355,18 +362,32 @@ server {
@@ -355,18 +362,32 @@ server {
access_log /var/log/nginx/${d}.access.log;
access_log /var/log/nginx/${d}.access.log;
error_log /var/log/nginx/${d}.error.log;
error_log /var/log/nginx/${d}.error.log;
- add_header X-Content-Type-Options nosniff always;
- add_header X-Frame-Options SAMEORIGIN always;
- add_header Referrer-Policy strict-origin-when-cross-origin always;
- add_header Strict-Transport-Security "max-age=31536000" always;
+ ${SECURITY_HEADERS.join('\n ')}
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ ${sec}
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ ${sec}
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ ${sec}
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ ${sec}
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -374,6 +395,7 @@ server {
@@ -374,6 +395,7 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ ${sec}
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -29,10 +29,39 @@ server {
@@ -29,10 +29,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -40,6 +69,10 @@ server {
@@ -40,6 +69,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -29,10 +29,39 @@ server {
@@ -29,10 +29,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -40,6 +69,10 @@ server {
@@ -40,6 +69,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -29,10 +29,39 @@ server {
@@ -29,10 +29,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -40,6 +69,10 @@ server {
@@ -40,6 +69,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -29,10 +29,39 @@ server {
@@ -29,10 +29,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -40,6 +69,10 @@ server {
@@ -40,6 +69,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -39,10 +39,39 @@ server {
@@ -39,10 +39,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -50,6 +79,10 @@ server {
@@ -50,6 +79,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -29,10 +29,39 @@ server {
@@ -29,10 +29,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -40,6 +69,10 @@ server {
@@ -40,6 +69,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -29,10 +29,39 @@ server {
@@ -29,10 +29,39 @@ server {
gzip on;
gzip on;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
gzip_types text/html text/plain text/css application/json application/javascript application/xml image/svg+xml application/manifest+json;
- location = /robots.txt { add_header Cache-Control "public, max-age=3600"; }
- location = /sitemap.xml { add_header Cache-Control "public, max-age=3600"; types { application/xml xml; } }
- location = /manifest.webmanifest { types { application/manifest+json webmanifest; } add_header Cache-Control "public, max-age=86400"; }
- location = /status.json { add_header Cache-Control "public, max-age=600"; add_header Access-Control-Allow-Origin "*"; }
+ # An add_header inside a location replaces the server's list (nginx does not merge them), so every
+ # location that sets its own header repeats the security headers.
+ location = /robots.txt {
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /sitemap.xml {
+ types { application/xml xml; }
+ add_header Cache-Control "public, max-age=3600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /manifest.webmanifest {
+ types { application/manifest+json webmanifest; }
+ add_header Cache-Control "public, max-age=86400";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
+ location = /status.json {
+ add_header Cache-Control "public, max-age=600";
+ add_header Access-Control-Allow-Origin "*";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
+ }
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
# Only the files in dist/ exist; anything else is a real 404 with a page, never the front page.
error_page 404 /404.html;
error_page 404 /404.html;
@@ -40,6 +69,10 @@ server {
@@ -40,6 +69,10 @@ server {
location / {
location / {
add_header Cache-Control "public, max-age=600";
add_header Cache-Control "public, max-age=600";
+ add_header X-Content-Type-Options nosniff always;
+ add_header X-Frame-Options SAMEORIGIN always;
+ add_header Referrer-Policy strict-origin-when-cross-origin always;
+ add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri $uri.html $uri/ =404;
try_files $uri $uri.html $uri/ =404;
}
}
@@ -60,6 +60,14 @@ for (const site of catalog.sites) {
@@ -60,6 +60,14 @@ for (const site of catalog.sites) {
assert.ok(conf.includes('error_page 404 /404.html;'), `${d}: vhost answers 404 with /404.html`);
assert.ok(conf.includes('error_page 404 /404.html;'), `${d}: vhost answers 404 with /404.html`);
assert.ok(conf.includes('try_files $uri $uri.html $uri/ =404;'), `${d}: vhost try_files ends in =404`);
assert.ok(conf.includes('try_files $uri $uri.html $uri/ =404;'), `${d}: vhost try_files ends in =404`);
assert.doesNotMatch(conf, /try_files[^;]*\/index\.html;/, `${d}: vhost never falls back to the front page`);
assert.doesNotMatch(conf, /try_files[^;]*\/index\.html;/, `${d}: vhost never falls back to the front page`);
+ // nginx drops the server-level add_header list in any location with its own add_header: each such
+ // location must repeat the security headers (they were missing from every Sites response until 2026-09-24).
+ for (const m of conf.matchAll(/location [^{]*\{((?:[^{}]|\{[^{}]*\})*)\}/g)) {
+ if (!/add_header/.test(m[1])) continue;
+ for (const h of ['X-Content-Type-Options', 'X-Frame-Options', 'Referrer-Policy', 'Strict-Transport-Security']) {
+ assert.ok(m[1].includes(`add_header ${h} `), `${d}: ${m[0].split('{')[0].trim()} repeats ${h}`);
+ }
+ }
}
}
// Labels come from facts (facts.json: each repository's STATUS.json + the Network registry), never a
// Labels come from facts (facts.json: each repository's STATUS.json + the Network registry), never a