Kurz erklärt
CSP steht für Content Security Policy und ist ein HTTP-Antwort-Header, der dem Browser eine Whitelist mitgibt: "Lade Skripte nur von diesen Quellen, Bilder nur von jenen, Schriften nur von diesen — und ignoriere alles andere." Wenn ein Angreifer es schafft, fremden Code in deine Webseite einzuschleusen (XSS), verhindert die CSP das Ausführen — der Browser blockiert die Quelle ganz einfach.
Beispiel-Header
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' https://fonts.gstatic.com; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
Die wichtigsten Direktiven
default-src— Fallback für alle nicht spezifizierten Direktiven.'self'= nur eigene Domain.script-src— Quellen für JavaScript. Hier darf'unsafe-inline'auf keinen Fall stehen, sonst ist die CSP wirkungslos gegen XSS.style-src— Quellen für CSS.'unsafe-inline'ist hier weniger kritisch, aber ein Code-Smell.img-src— Bilder.data:erlaubt Base64-Bilder,https:erlaubt Bilder von beliebigen HTTPS-Quellen.connect-src— XHR/Fetch/WebSocket-Ziele. Wichtig bei API-Calls auf andere Domains.frame-ancestors— wer darf deine Seite in einem iframe einbetten?'none'= niemand. Ersetzt den älteren Header X-Frame-Options.base-uri— verhindert das Manipulieren von<base>-Tags durch XSS.form-action— wohin dürfen Formulare schicken? Default: alle Domains erlaubt — was ein XSS-Risiko ist.
unsafe-inline vermeiden
Eine CSP mit script-src 'unsafe-inline'
erlaubt jedes Inline-Skript auf der Seite — und damit auch jedes injected Skript eines
Angreifers. Die CSP wird dadurch wirkungslos. Ersatz:
- Nonces: Jeder Request bekommt einen zufälligen Nonce, der in der CSP und im Inline-Skript-Tag steht. Nur Skripte mit dem richtigen Nonce werden ausgeführt.
- Hashes: Du listest die SHA-256/384-Hashes deiner Inline-Skripte in der CSP auf. Funktioniert für statische Inhalte.
- Externe Files: Inline-Skripte in eigene .js-Dateien verschieben.
CSP einführen
Eine zu strikte CSP zerschießt Funktionen — Tracking, eingebettete Tweets, Analytics, Live-Chat-Widgets, Stripe-Buttons, Google-Maps. Empfohlene Reihenfolge:
- Report-Only-Modus: Aktiviere die CSP zunächst als
Content-Security-Policy-Report-Onlymitreport-tooderreport-uri. Verstöße werden gemeldet, aber nichts wird blockiert. - 2–4 Wochen sammeln: Tools wie Sentry, csp-report-collector oder ein eigener Endpunkt sammeln die Reports.
- Liste pflegen: Alle legitimen Quellen aufnehmen, illegitime ignorieren oder beheben.
- Enforce: Header umschalten auf
Content-Security-Policyohne-Report-Only.
Häufige Fehler
- 'unsafe-inline' bei script-src: Macht die CSP wirkungslos gegen XSS — die häufigste Schwachstelle.
- 'unsafe-eval': Erlaubt
eval(),new Function(),setTimeout(string)— sollte vermieden werden. - '*' als Quelle: Lädt von beliebigen HTTPS-Servern. Quasi keine Schutzwirkung.
- frame-ancestors fehlt: X-Frame-Options ist veraltet, frame-ancestors ist die moderne Variante. Auf
'none'oder'self'setzen.