CSP für Nginx konfigurieren
Schritt-für-Schritt-Anleitung: Content Security Policy auf Nginx einrichten, testen und aktivieren — mit fertigen Konfigurationen zum Kopieren.
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.
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.
# 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; 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.
sudo nginx -t && sudo systemctl reload nginx 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.com → style-src, fonts.gstatic.com → font-src |
| Google Analytics blockiert | *.google-analytics.com *.googletagmanager.com → script-src |
| WebSocket blockiert | wss://domain.tld → connect-src |
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.
# 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; Reporting-Endpoints-Header bei, um auch im Enforcement-Modus Violations zu erfassen. sudo nginx -t && sudo systemctl reload nginx 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.
# 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; <!-- 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> 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.