CSP für Nginx konfigurieren

Schritt-für-Schritt-Anleitung: Content Security Policy auf Nginx einrichten, testen und aktivieren — mit fertigen Konfigurationen zum Kopieren.

Nginx · Schritt für Schritt

Content Security Policy auf Nginx

Content Security Policy (CSP) ist der wichtigste HTTP-Security-Header gegen Cross-Site Scripting (XSS). Er teilt dem Browser mit, welche Ressourcen auf einer Seite geladen werden dürfen — und blockiert alles andere. CSP ist mit 35 von 166 Punkten der einflussreichste Header im Wolf-Agents Web Security Check.

Nginx unterstützt CSP nativ über die add_header-Direktive — keine zusätzlichen Module nötig. Diese Anleitung zeigt die Implementierung in vier Schritten: vom sicheren Testen bis zur Produktivkonfiguration.

1 Schritt 1 von 4

Report-Only Modus starten

Beginnen Sie immer im Report-Only-Modus. Der Browser meldet CSP-Verstöße in der Konsole und an Ihren Reporting-Endpoint, blockiert aber keine Ressourcen. So können Sie die Policy in Ruhe anpassen, ohne dass Ihre Website für Besucher kaputt geht.

/etc/nginx/conf.d/csp.conf Report-Only
# Report-Only CSP — meldet Violations, blockiert nichts
add_header Reporting-Endpoints
  'csp-endpoint="https://ihre-domain.de/api/csp-report"'
  always;

add_header Content-Security-Policy-Report-Only
  "default-src 'self';
   script-src 'self';
   style-src 'self' 'unsafe-inline';
   img-src 'self' data: https:;
   font-src 'self';
   connect-src 'self';
   frame-ancestors 'self';
   object-src 'none';
   base-uri 'self';
   form-action 'self';
   report-uri /api/csp-report;
   report-to csp-endpoint"
  always;
Warum always?

Ohne das always-Keyword setzt Nginx den Header nur bei erfolgreichen Responses (2xx/3xx). Mit always wird der CSP-Header auch bei Fehlerseiten (404, 500) gesetzt — wichtig, weil Angreifer gezielt Fehlerseiten für XSS nutzen.

Konfiguration prüfen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
2 Schritt 2 von 4

Violations analysieren und CSP anpassen

Öffnen Sie die Browser DevTools (F12) → Console. CSP-Violations erscheinen als Warnungen mit der blockierten Ressource und der verantwortlichen Direktive. Passen Sie die Policy an, bis keine unerwarteten Violations mehr auftreten.

Violation Lösung
Inline-Script blockiert Nonce oder Hash hinzufügen (siehe Schritt 4)
Externe Bibliothek blockiert Domain zu script-src hinzufügen
Google Fonts blockiert fonts.googleapis.comstyle-src, fonts.gstatic.comfont-src
Google Analytics blockiert *.google-analytics.com *.googletagmanager.comscript-src
WebSocket blockiert wss://domain.tldconnect-src
Lassen Sie die Policy mindestens 1 Woche im Report-Only-Modus laufen, bevor Sie zu Enforcement wechseln. So erfassen Sie auch selten besuchte Seiten und Edge Cases.
3 Schritt 3 von 4

Enforcement aktivieren

Wenn keine unerwarteten Violations mehr auftreten, ändern Sie den Header-Namen. Entfernen Sie -Report-Only — der Browser blockiert ab sofort nicht autorisierte Ressourcen.

/etc/nginx/conf.d/csp.conf Produktiv
# Produktions-CSP — blockiert nicht autorisierte Ressourcen
add_header Content-Security-Policy
  "default-src 'self';
   script-src 'self';
   style-src 'self' 'unsafe-inline';
   img-src 'self' data: https:;
   font-src 'self';
   connect-src 'self';
   frame-ancestors 'self';
   object-src 'none';
   base-uri 'self';
   form-action 'self'"
  always;
Testen Sie gründlich auf allen Seiten — inklusive Login, Checkout und Admin-Bereich — bevor Sie den Report-Only-Modus verlassen. Behalten Sie den Reporting-Endpoints-Header bei, um auch im Enforcement-Modus Violations zu erfassen.
Konfiguration prüfen und neu laden:
sudo nginx -t && sudo systemctl reload nginx
4 Schritt 4 von 4 · Fortgeschritten

Nonces einrichten für maximale Sicherheit

Nonces sind einmalige Token, die bei jedem Request neu generiert werden. Mit Nonces können Sie 'unsafe-inline' aus Ihrer CSP entfernen — das höchste Sicherheitsniveau. Nginx selbst kann keine Nonces generieren; dafür benötigen Sie OpenResty (Nginx + Lua) oder einen Backend-Proxy.

nginx.conf (OpenResty / ngx_http_lua_module) Nonces
# Dynamische CSP-Nonces mit OpenResty
set_by_lua_block $csp_nonce {
  -- 16 Bytes Zufall → Base64-kodiert
  return ngx.encode_base64(
    require("resty.random").bytes(16)
  )
}

# CSP-Header mit Nonce + strict-dynamic
add_header Content-Security-Policy
  "default-src 'self';
   script-src 'nonce-$csp_nonce' 'strict-dynamic';
   style-src 'self' 'unsafe-inline';
   img-src 'self' data: https:;
   object-src 'none';
   base-uri 'self';
   form-action 'self'"
  always;
HTML-Template
<!-- Nonce im Script-Tag referenzieren -->
<script nonce="$csp_nonce">
  console.log('Dieses Script ist autorisiert');
</script>

<!-- Externe Scripts erben Vertrauen durch strict-dynamic -->
<script nonce="$csp_nonce" src="/main.js"></script>
Ohne OpenResty?

Wenn Sie Standard-Nginx ohne Lua-Modul nutzen, können Sie Nonces über Ihr Backend (z.B. PHP, Node.js, Python) generieren und den CSP-Header dort setzen. Nginx leitet den Header dann unverändert weiter. Alternativ: Hash-basierte CSP für statische Inline-Scripts.

Wie steht Ihre Domain bei Content Security Policy?

Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.