Sicherstellen, dass die CSP effektiv gegen XSS-Angriffe abwehrt

Mit einer Content Security Policy (CSP) wird sichergestellt, dass alle auf der Seite geladenen Inhalte vom Websiteinhaber als vertrauenswürdig eingestuft werden. CSPs können Cross-Site-Scripting-Angriffe (XSS) abwehren, da sie unsichere Scripts blockieren, die von Angreifern eingeschleust werden. Der CSP kann jedoch leicht umgangen werden, wenn er nicht streng genug ist. Weitere Informationen finden Sie unter Cross-Site-Scripting (XSS) mit einer strengen Content Security Policy (CSP) minimieren. Lighthouse erfasst CSPs, die für das Hauptdokument erzwungen werden, und meldet Probleme vom CSP Evaluator, wenn sie umgangen werden können.

Lighthouse-Bericht warnt, dass im erzwungenen Modus kein CSP gefunden wurde.
Warnung im Lighthouse-Bericht, dass im erzwungenen Modus kein CSP gefunden wurde

Erforderliche Praktiken für eine nicht umgehbare CSP

Mit den folgenden Maßnahmen können Sie dafür sorgen, dass Ihr CSP nicht umgangen werden kann. Wenn der CSP umgangen werden kann, gibt Lighthouse eine Warnung mit hoher Schwere aus.

CSP-Ziel: XSS

Um XSS zu verhindern, sollte eine CSP die Anweisungen script-src, object-src und base-uri enthalten. Die CSP darf auch keine Syntaxfehler enthalten.

Mit script-src und object-src werden Seiten vor unsicheren Scripts bzw. unsicheren Plug-ins geschützt. Alternativ können Sie mit default-src eine allgemeine Richtlinie anstelle von vielen Anweisungen wie script-src und object-src konfigurieren.

base-uri verhindert die Einschleusung nicht autorisierter <base>-Tags, mit denen alle relativen URLs (z. B. Scripts) auf eine von Angreifern kontrollierte Domain weitergeleitet werden können.

CSP verwendet Nonces oder Hashes, um Umgehung der Zulassungsliste zu verhindern

Ein CSP, der eine Zulassungsliste für script-src konfiguriert, geht davon aus, dass alle Antworten von einer vertrauenswürdigen Domain sicher sind und als Scripts ausgeführt werden können. Bei modernen Anwendungen ist das jedoch nicht der Fall. Einige gängige, harmlose Muster wie das Bereitstellen von JSONP-Schnittstellen und das Hosten von Kopien der AngularJS-Bibliothek ermöglichen es Angreifern, die Einschränkungen von CSP zu umgehen.

In der Praxis kann es für Anwendungsentwickler zwar nicht offensichtlich sein, aber die meisten script-src-Zulassungslisten können von einem Angreifer mit einem XSS-Bug umgangen werden und bieten nur wenig Schutz vor Script-Injection. Im Gegensatz dazu sind die noncebasierten und hashbasierten Ansätze nicht von diesen Problemen betroffen und erleichtern die Einführung und Einhaltung einer sichereren Richtlinie.

In diesem Code wird beispielsweise ein JSONP-Endpunkt verwendet, der auf einer vertrauenswürdigen Domain gehostet wird, um ein von einem Angreifer kontrolliertes Script einzuschleusen:

CSP:

script-src https://trusted.example.com

HTML:

<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>

Um eine Umgehung zu verhindern, sollte ein CSP Scripts einzeln mithilfe von Nonces oder Hashes zulassen und „strict-dynamic“ anstelle einer Zulassungsliste verwenden.

Zusätzliche Empfehlungen für einen sicheren CSP

Implementieren Sie die folgenden Praktiken für zusätzliche Sicherheit und Kompatibilität. Wenn der CSP eine der Empfehlungen nicht befolgt, gibt Lighthouse eine Warnung mit mittlerer Schwere aus.

CSP-Berichte konfigurieren

Wenn du ein Ziel für die Berichterstellung konfigurierst, kannst du Unterbrechungen besser im Blick behalten. Sie können das Ziel für die Berichterstellung mit den Anweisungen report-uri oder report-to festlegen. report-to wird derzeit nicht von allen modernen Browsern unterstützt. Daher wird empfohlen, beide oder nur report-uri zu verwenden.

Wenn Inhalte gegen die CSP verstoßen, sendet der Browser einen Bericht an das konfigurierte Ziel. Achten Sie darauf, dass an diesem Ziel eine Anwendung konfiguriert ist, die diese Berichte verarbeitet.

CSP in einem HTTP-Header definieren

Eine CSP kann in einem Meta-Tag so definiert werden:

<meta http-equiv="Content-Security-Policy" content="script-src 'none'">

Wenn möglich, sollten Sie jedoch eine CSP in einem HTTP-Antwortheader definieren. Eine Injection vor dem Meta-Tag führt dazu, dass der CSP umgangen wird. Außerdem werden frame-ancestors, sandbox und die Berichterstellung in Meta-Tag-CSPs nicht unterstützt.

Rückwärtskompatibilität von CSP

Nicht alle Browser unterstützen CSP-Nonces/-Hashes. Daher wird empfohlen, unsafe-inline als Fallback für nicht konforme Browser hinzuzufügen. Wenn der Browser Nonces/Hashes unterstützt, wird unsafe-inline ignoriert.

Ebenso wird strict-dynamic nicht von allen Browsern unterstützt. Wir empfehlen, eine Zulassungsliste als Fallback für nicht konforme Browser festzulegen. Die Zulassungsliste wird in Browsern, die strict-dynamic unterstützen, ignoriert.

Einen strengen CSP entwickeln

Unten sehen Sie ein Beispiel für die Verwendung einer strikten CSP mit einer noncebasierten Richtlinie.

CSP:

script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;

HTML:

<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>

random123 ist ein Base64-String, der jedes Mal serverseitig generiert wird, wenn die Seite geladen wird. unsafe-inline und https: werden in modernen Browsern aufgrund des Nonces und strict-dynamic ignoriert. Weitere Informationen zur Verwendung eines strengen CSP finden Sie im Leitfaden für strenge CSPs.

Mit Lighthouse und dem CSP-Evaluator können Sie eine CSP auf potenzielle Umgehungsmöglichkeiten prüfen. Wenn Sie einen neuen CSP testen möchten, ohne das Risiko einzugehen, dass vorhandene Seiten nicht mehr korrekt angezeigt werden, definieren Sie den CSP im reinen Berichtsmodus. Verwenden Sie dazu Content-Security-Policy-Report-Only als Headernamen. Dadurch werden CSP-Verstöße an alle Ziele für die Berichterstellung gesendet, die Sie mit report-to und report-uri konfiguriert haben. Die CSP wird jedoch nicht erzwungen.