fix(nginx): Security-Header in überschreibenden location-Blöcken wiederholen
nginx vererbt add_header nicht in Blöcke, die eigene add_header setzen. Dadurch gingen X-Frame-Options, X-Content-Type-Options und X-XSS-Protection ausgerechnet bei den HTML-Antworten verloren – jeder location-Block mit Cache-Control hat sie stillschweigend abgeschaltet. Verifiziert: nginx -t ist für alle drei Konfigurationen erfolgreich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
81b21da499
commit
474383d17b
|
|
@ -27,19 +27,28 @@ server {
|
||||||
gzip_types text/plain text/xml application/xml+rss application/json;
|
gzip_types text/plain text/xml application/xml+rss application/json;
|
||||||
gzip_disable "msie6";
|
gzip_disable "msie6";
|
||||||
|
|
||||||
# Security headers
|
# Security headers.
|
||||||
|
# ACHTUNG: nginx vererbt add_header nicht in Bloecke, die eigene add_header
|
||||||
|
# setzen - deshalb sind diese drei Zeilen in jedem solchen location-Block
|
||||||
|
# wiederholt. Beim Anlegen neuer Bloecke mit add_header daran denken.
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
# Cache static assets (images, fonts)
|
# Cache static assets (images, fonts)
|
||||||
location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
expires 1y;
|
expires 1y;
|
||||||
add_header Cache-Control "public, immutable";
|
add_header Cache-Control "public, immutable";
|
||||||
}
|
}
|
||||||
|
|
||||||
# JS and CSS - no compression, short cache
|
# JS and CSS - no compression, short cache
|
||||||
location ~* \.(js|css)$ {
|
location ~* \.(js|css)$ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
expires 1h;
|
expires 1h;
|
||||||
add_header Cache-Control "public, no-transform";
|
add_header Cache-Control "public, no-transform";
|
||||||
gzip off;
|
gzip off;
|
||||||
|
|
@ -47,6 +56,9 @@ server {
|
||||||
|
|
||||||
# Service Worker - never cache
|
# Service Worker - never cache
|
||||||
location = /sw.js {
|
location = /sw.js {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
expires 0;
|
||||||
}
|
}
|
||||||
|
|
@ -79,6 +91,9 @@ server {
|
||||||
|
|
||||||
# Service Worker for subpath deployment
|
# Service Worker for subpath deployment
|
||||||
location = /drohnenfuehrer/sw.js {
|
location = /drohnenfuehrer/sw.js {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
expires 0;
|
||||||
alias /usr/share/nginx/html/sw.js;
|
alias /usr/share/nginx/html/sw.js;
|
||||||
|
|
@ -86,6 +101,9 @@ server {
|
||||||
|
|
||||||
# index.html - never cache so new builds are picked up immediately
|
# index.html - never cache so new builds are picked up immediately
|
||||||
location = /index.html {
|
location = /index.html {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
add_header Pragma "no-cache";
|
add_header Pragma "no-cache";
|
||||||
expires 0;
|
expires 0;
|
||||||
|
|
@ -93,6 +111,9 @@ server {
|
||||||
|
|
||||||
# SPA fallback for subpath deployment (/drohnenfuehrer)
|
# SPA fallback for subpath deployment (/drohnenfuehrer)
|
||||||
location ^~ /drohnenfuehrer/ {
|
location ^~ /drohnenfuehrer/ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
rewrite ^/drohnenfuehrer(/.*)$ $1 break;
|
rewrite ^/drohnenfuehrer(/.*)$ $1 break;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
|
|
@ -102,6 +123,9 @@ server {
|
||||||
|
|
||||||
# SPA fallback - serve index.html for all routes
|
# SPA fallback - serve index.html for all routes
|
||||||
location / {
|
location / {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
add_header Pragma "no-cache";
|
add_header Pragma "no-cache";
|
||||||
|
|
@ -110,6 +134,9 @@ server {
|
||||||
|
|
||||||
# Health check endpoint
|
# Health check endpoint
|
||||||
location /health {
|
location /health {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
access_log off;
|
access_log off;
|
||||||
return 200 "OK\n";
|
return 200 "OK\n";
|
||||||
add_header Content-Type text/plain;
|
add_header Content-Type text/plain;
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,28 @@ server {
|
||||||
gzip_types text/plain text/xml application/xml+rss application/json;
|
gzip_types text/plain text/xml application/xml+rss application/json;
|
||||||
gzip_disable "msie6";
|
gzip_disable "msie6";
|
||||||
|
|
||||||
# Security headers
|
# Security headers.
|
||||||
|
# ACHTUNG: nginx vererbt add_header nicht in Bloecke, die eigene add_header
|
||||||
|
# setzen - deshalb sind diese drei Zeilen in jedem solchen location-Block
|
||||||
|
# wiederholt. Beim Anlegen neuer Bloecke mit add_header daran denken.
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
# Cache static assets (images, fonts)
|
# Cache static assets (images, fonts)
|
||||||
location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
expires 1y;
|
expires 1y;
|
||||||
add_header Cache-Control "public, immutable";
|
add_header Cache-Control "public, immutable";
|
||||||
}
|
}
|
||||||
|
|
||||||
# JS and CSS - no compression, short cache
|
# JS and CSS - no compression, short cache
|
||||||
location ~* \.(js|css)$ {
|
location ~* \.(js|css)$ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
expires 1h;
|
expires 1h;
|
||||||
add_header Cache-Control "public, no-transform";
|
add_header Cache-Control "public, no-transform";
|
||||||
gzip off;
|
gzip off;
|
||||||
|
|
@ -47,6 +56,9 @@ server {
|
||||||
|
|
||||||
# Service Worker - never cache
|
# Service Worker - never cache
|
||||||
location = /sw.js {
|
location = /sw.js {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
expires 0;
|
||||||
}
|
}
|
||||||
|
|
@ -79,6 +91,9 @@ server {
|
||||||
|
|
||||||
# Service Worker for subpath deployment
|
# Service Worker for subpath deployment
|
||||||
location = /nachsuche/sw.js {
|
location = /nachsuche/sw.js {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
expires 0;
|
||||||
alias /usr/share/nginx/html/sw.js;
|
alias /usr/share/nginx/html/sw.js;
|
||||||
|
|
@ -86,6 +101,9 @@ server {
|
||||||
|
|
||||||
# index.html - never cache so new builds are picked up immediately
|
# index.html - never cache so new builds are picked up immediately
|
||||||
location = /index.html {
|
location = /index.html {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
add_header Pragma "no-cache";
|
add_header Pragma "no-cache";
|
||||||
expires 0;
|
expires 0;
|
||||||
|
|
@ -93,6 +111,9 @@ server {
|
||||||
|
|
||||||
# SPA fallback for subpath deployment (/nachsuche)
|
# SPA fallback for subpath deployment (/nachsuche)
|
||||||
location ^~ /nachsuche/ {
|
location ^~ /nachsuche/ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
rewrite ^/nachsuche(/.*)$ $1 break;
|
rewrite ^/nachsuche(/.*)$ $1 break;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
|
|
@ -102,6 +123,9 @@ server {
|
||||||
|
|
||||||
# SPA fallback - serve index.html for all routes
|
# SPA fallback - serve index.html for all routes
|
||||||
location / {
|
location / {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
add_header Pragma "no-cache";
|
add_header Pragma "no-cache";
|
||||||
|
|
@ -110,6 +134,9 @@ server {
|
||||||
|
|
||||||
# Health check endpoint
|
# Health check endpoint
|
||||||
location /health {
|
location /health {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
access_log off;
|
access_log off;
|
||||||
return 200 "OK\n";
|
return 200 "OK\n";
|
||||||
add_header Content-Type text/plain;
|
add_header Content-Type text/plain;
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,28 @@ server {
|
||||||
gzip_types text/plain text/xml application/xml+rss application/json;
|
gzip_types text/plain text/xml application/xml+rss application/json;
|
||||||
gzip_disable "msie6";
|
gzip_disable "msie6";
|
||||||
|
|
||||||
# Security headers
|
# Security headers.
|
||||||
|
# ACHTUNG: nginx vererbt add_header nicht in Bloecke, die eigene add_header
|
||||||
|
# setzen - deshalb sind diese drei Zeilen in jedem solchen location-Block
|
||||||
|
# wiederholt. Beim Anlegen neuer Bloecke mit add_header daran denken.
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
# Cache static assets (images, fonts)
|
# Cache static assets (images, fonts)
|
||||||
location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
expires 1y;
|
expires 1y;
|
||||||
add_header Cache-Control "public, immutable";
|
add_header Cache-Control "public, immutable";
|
||||||
}
|
}
|
||||||
|
|
||||||
# JS and CSS - no compression, short cache
|
# JS and CSS - no compression, short cache
|
||||||
location ~* \.(js|css)$ {
|
location ~* \.(js|css)$ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
expires 1h;
|
expires 1h;
|
||||||
add_header Cache-Control "public, no-transform";
|
add_header Cache-Control "public, no-transform";
|
||||||
gzip off;
|
gzip off;
|
||||||
|
|
@ -47,6 +56,9 @@ server {
|
||||||
|
|
||||||
# Service Worker - never cache
|
# Service Worker - never cache
|
||||||
location = /sw.js {
|
location = /sw.js {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
expires 0;
|
||||||
}
|
}
|
||||||
|
|
@ -79,6 +91,9 @@ server {
|
||||||
|
|
||||||
# Service Worker for subpath deployment
|
# Service Worker for subpath deployment
|
||||||
location = /stoeberhunde/sw.js {
|
location = /stoeberhunde/sw.js {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
expires 0;
|
||||||
alias /usr/share/nginx/html/sw.js;
|
alias /usr/share/nginx/html/sw.js;
|
||||||
|
|
@ -86,6 +101,9 @@ server {
|
||||||
|
|
||||||
# index.html - never cache so new builds are picked up immediately
|
# index.html - never cache so new builds are picked up immediately
|
||||||
location = /index.html {
|
location = /index.html {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
add_header Pragma "no-cache";
|
add_header Pragma "no-cache";
|
||||||
expires 0;
|
expires 0;
|
||||||
|
|
@ -93,6 +111,9 @@ server {
|
||||||
|
|
||||||
# SPA fallback for subpath deployment (/stoeberhunde)
|
# SPA fallback for subpath deployment (/stoeberhunde)
|
||||||
location ^~ /stoeberhunde/ {
|
location ^~ /stoeberhunde/ {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
rewrite ^/stoeberhunde(/.*)$ $1 break;
|
rewrite ^/stoeberhunde(/.*)$ $1 break;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
|
|
@ -102,6 +123,9 @@ server {
|
||||||
|
|
||||||
# SPA fallback - serve index.html for all routes
|
# SPA fallback - serve index.html for all routes
|
||||||
location / {
|
location / {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
add_header Pragma "no-cache";
|
add_header Pragma "no-cache";
|
||||||
|
|
@ -110,6 +134,9 @@ server {
|
||||||
|
|
||||||
# Health check endpoint
|
# Health check endpoint
|
||||||
location /health {
|
location /health {
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
access_log off;
|
access_log off;
|
||||||
return 200 "OK\n";
|
return 200 "OK\n";
|
||||||
add_header Content-Type text/plain;
|
add_header Content-Type text/plain;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue