Security Header

Content Security Policy (CSP) im Detail: Schutz vor XSS

Die Content Security Policy (CSP) ist einer der mächtigsten und zugleich komplexesten Security Header zur Absicherung von Webanwendungen. Sie dient als effektive Schutzmauer gegen Cross-Site Scripting (XSS) und Data-Injection-Angriffe. Über die CSP teilt der Server dem Browser – als HTTP-Response-Header – eine Whitelist von vertrauenswürdigen Quellen mit, von denen Skripte, Styles, Bilder oder Verbindungen geladen und ausgeführt werden dürfen. Alles, was nicht auf dieser Liste steht, blockiert der Browser rigoros. Konkrete Vorlagen finden Sie in den CSP Best Practices.

Das Kernproblem: Unkontrollierte Skript-Ausführung

Ohne CSP vertraut ein Browser jedem JavaScript-Code, der im HTML-Dokument steht. Gelingt es einem Angreifer, eigenen Code (z. B. über manipulierte Benutzereingaben oder gehackte Drittanbieter-Skripte) in die Seite einzuschleusen, führt der Browser diesen aus. Der Angreifer kann dann Cookies stehlen, Logins fälschen oder Kundendaten abfangen.

Die CSP löst dieses Problem, indem sie dem Browser die Ausführung unautorisierter Skripte verbietet.


Die wichtigsten CSP-Direktiven (Directives)

Eine Content Security Policy wird als Response-Header mit einer Reihe von Direktiven deklariert:

Content-Security-Policy: default-src 'self'; script-src 'self' https://trustedscripts.com; img-src 'self' data:;
  • default-src: Der Fallback für fast alle anderen Direktiven. Steht hier 'self', dürfen Ressourcen standardmässig nur von der eigenen Domain geladen werden.
  • script-src: Definiert die erlaubten Quellen für JavaScript.
  • style-src: Regelt, von welchen Domains CSS-Dateien geladen werden dürfen.
  • img-src: Bestimmt die erlaubten Quellen für Bilder (z. B. 'self' oder data: für Inline-Base64-Grafiken).
  • frame-ancestors: Legt fest, welche Domains diese Website in einem iframe einbetten dürfen. Dies ist der moderne, standardisierte Nachfolger des älteren X-Frame-Options-Headers.

Das Verbot von Inline-Skripten und die Lösung

Eine sichere CSP verbietet standardmässig die Ausführung von direkt im HTML eingebetteten Skripten (z. B. <script>alert('XSS')</script> oder Inline-Event-Handlern wie onclick="..."). Das Schlüsselwort 'unsafe-inline' hebt dieses Verbot auf, schwächt die CSP jedoch dramatisch ab und sollte im produktiven Einsatz vermieden werden.

Um legitime Inline-Skripte dennoch sicher auszuführen, bietet die CSP zwei Verfahren:

A. Nonces (Kryptografische Einmal-Schlüssel)

Der Server generiert bei jedem Seitenaufruf einen zufälligen, kryptografischen Wert (Nonce) und fügt ihn sowohl im CSP-Header als auch im HTML-Tag hinzu:

  • Header: script-src 'nonce-d3g8a2k9'
  • HTML: <script nonce="d3g8a2k9">console.log('Sicher')</script> Da ein Angreifer den dynamischen Nonce-Wert nicht erraten kann, blockiert der Browser nicht-autorisierte Skripte ohne passenden Nonce.

B. Hashes (Kryptografische Prüfsummen)

Der Server berechnet vorab den SHA-256-Hash des Inline-Skripts und hinterlegt diesen im CSP-Header.

  • Header: script-src 'sha256-R3x5v...' Der Browser vergleicht vor der Ausführung den Hashwert des Skripts im HTML mit dem Wert im Header. Stimmen sie überein, wird das Skript ausgeführt.

Überwachung durch Reporting

Mit den Tags report-uri oder report-to können Sie den Browser anweisen, jeden Verstoss gegen die CSP automatisch als JSON-Bericht an einen Server zu senden. Dies ist äusserst wertvoll, um unbemerkte XSS-Angriffe im Live-Betrieb aufzudecken oder Fehler bei der eigenen CSP-Konfiguration schnell zu beheben.

Schwache vs. starke CSP im direkten Vergleich

Eine CSP mit unsafe-inline bietet kaum Schutz vor XSS, weil eingeschleuste Inline-Skripte weiterhin ausgeführt werden. Die folgende Gegenüberstellung zeigt den Unterschied:

AspektSchwach (vermeiden)Stark (empfohlen)
script-src'self' 'unsafe-inline''self' 'nonce-rAnd0m'
Inline-Skripteuneingeschränkt erlaubtnur mit gültigem Nonce
object-srcnicht gesetzt'none'
base-urinicht gesetzt'self'
XSS-Schutzpraktisch keinerhoch

Schwach (vermeiden):

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'

Stark (empfohlen, Nonce-basiert):

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-rAnd0m'; object-src 'none'; base-uri 'self'

Jedes erlaubte Skript erhält dann ein passendes Nonce-Attribut (<script nonce="rAnd0m">). Ergänzend sollten Sie verwandte Header wie X-Frame-Options bzw. frame-ancestors setzen und Ihre gesamte Konfiguration mit der Security-Header-Checkliste abgleichen.

Typische Fehlkonfigurationen

FehlerRisikoBesser
'unsafe-inline' im script-srcXSS bleibt möglichNonces oder Hashes nutzen
default-src *Alles erlaubt, kein Schutzrestriktiv mit 'self' starten
object-src vergessenFlash/Plugin-Injectionobject-src 'none'
Direkt scharf statt Report-OnlyFunktionsausfälleerst Report-Only testen

[!TIP] Das Erstellen einer fehlerfreien, restriktiven Content Security Policy ist eine anspruchsvolle Aufgabe, die durch das Hinzufügen neuer Funktionen auf der Website stetig angepasst werden muss. Analysieren Sie Ihre CSP und decken Sie Schwachstellen auf mit dem kostenlosen CSP Evaluator auf balou.tools.

Häufig gestellte Fragen (FAQ)

Wie schützt eine CSP vor Cross-Site Scripting (XSS)?

Selbst wenn ein Angreifer erfolgreich Schadcode in Ihre Website einschleust (z. B. durch ein unsicheres Gästebuch), blockiert der Browser die Ausführung dieses Skripts, sofern die Domain des Angreifers nicht explizit in der CSP-Whitelist freigegeben ist.

Was bewirkt der Status „Report-Only“?

Mit dem Header `Content-Security-Policy-Report-Only` können Sie eine CSP testen. Verstösse werden an eine definierte URL gemeldet (Report-To), aber der Browser blockiert die Skripte noch nicht. Dies verhindert Ausfälle beim Testen neuer Regeln.