Implementierung der Content Security Policy (CSP)
Der Content-Security-Policy HTTP-Header bietet eine detaillierte Kontrolle über den Code, der auf einer Website geladen werden kann, und was damit gemacht werden darf.
Problem
Das Hauptproblem, auf das dieser Artikel abzielt, sind Cross-Site-Scripting (XSS) Angriffe. Diese resultieren im Allgemeinen aus einem Mangel an Kontrolle und Bewusstsein über die Quellen, aus denen Website-Ressourcen geladen werden. Dieses Problem wird schwerer zu handhaben, je größer und komplexer Websites werden und immer mehr auf Drittpartei-Ressourcen wie JavaScript-Bibliotheken angewiesen sind.
Hinweis: CSP ist ein Teil einer umfassenden Strategie zum Schutz vor XSS-Angriffen. Es gibt noch andere Faktoren, wie Ausgabe-Codierung und Bereinigung, die ebenfalls wichtig sind.
CSP kann auch helfen, andere Probleme zu beheben, die in anderen Artikeln behandelt werden:
- Verhindern von Clickjacking indem verhindert wird, dass Ihre Website in
<iframe>-Elemente eingebettet wird. Dies geschieht mithilfe der CSP-Richtlinieframe-ancestors. - Verhindern von Man-in-the-Middle (MiTM) Angriffen durch das Upgrade jeglicher HTTP-Verbindungen auf HTTPS. Dies wird durch die CSP-Richtlinie
upgrade-insecure-requestsunterstützt. Siehe Upgrading insecure requests.
Lösung
Die Implementierung einer strikten CSP ist der beste Weg, um XSS-Schwachstellen mit CSP zu mildern. Dies verwendet nonce- oder hashbasierte Abrufrichtlinien, um sicherzustellen, dass nur Skripte und/oder Stile ausgeführt werden, die das korrekte Nonce oder den korrekten Hash enthalten. JavaScript, das von einem Hacker eingefügt wird, läuft einfach nicht.
Strikte CSPs:
- Deaktivieren die Verwendung von unsicherem Inline-JavaScript, das heißt Inline-Ereignishandler-Attribute wie
onclick. Dies verhindert, dass nicht ordnungsgemäß maskierte Benutzereingaben vom Webbrowser als JavaScript interpretiert werden. - Deaktivieren die Verwendung von riskanten API-Aufrufen wie
eval(), was ein weiterer Effekt derscript-src-Richtlinie ist. - Deaktivieren das Einbetten aller Objekte über
object-src 'none'. - Verhindern die Verwendung des
<base>-Elements zur Setzung einer Basis-URI überbase-uri 'none';.
Strikte CSPs werden gegenüber standortbasierten Richtlinien, auch Erlaubnislistenrichtlinien genannt, bevorzugt, bei denen Sie angeben, von welchen Domains Skripte ausgeführt werden dürfen. Erlaubnislistenrichtlinien erlauben oft unsichere Domains, wodurch der gesamte Zweck einer CSP zunichtegemacht wird, und sie können sehr groß und unhandlich werden, besonders wenn Sie versuchen, Dienste zu erlauben, die viele Drittanbieter-Skripte benötigen.
Schritte zur Implementierung von CSP
Implementieren Sie eine strikte CSP und beginnen Sie dann, Ressourcen zu identifizieren, die aufgrund der Richtlinie nicht geladen werden können, und ergreifen Sie Maßnahmen, um diese Probleme zu umgehen.
Hinweis:
Bevor Sie irgendeine tatsächliche CSP mit dem Content-Security-Policy-Header implementieren, wird empfohlen, diese zuerst mit dem Content-Security-Policy-Report-Only HTTP-Header zu testen; siehe Bericht-only CSPs unten.
- Entscheiden Sie, ob Sie Nonces oder Hashes verwenden möchten. Sie sollten Nonces verwenden, wenn Sie Inhalte dynamisch generieren können, oder Hashes, wenn Sie statische Inhalte bereitstellen müssen.
- Implementieren Sie eine strikte CSP, wie im Abschnitt Lösung beschrieben. Stellen Sie sicher, dass externe und interne Skripte (eingeschlossen über
<script>-Elemente), die Sie ausführen möchten, die korrekte Nonce in dienonce-Attribute vom Server eingefügt haben. Wenn Sie stattdessen Hashes verwenden, sollten externe Skripte den korrekten Hash imintegrity-Attribut haben. - Wenn ein erlaubtes Skript Drittanbieter-Skripte lädt, werden diese Skripte nicht geladen, da ihnen die erforderliche Nonce oder der Hash fehlt. Beheben Sie dieses Problem, indem Sie die
strict-dynamic-Richtlinie hinzufügen, die Skripte, die vom ersten Skript geladen werden, ohne explizit eine Nonce oder einen Hash zu erhalten, dasselbe Vertrauensniveau gibt. - Überarbeiten Sie Muster, die durch die strikte CSP nicht erlaubt sind, wie Inline-Ereignishandler und
eval(). Ersetzen Sie zum Beispiel Inline-Ereignishandler mitaddEventListener()-Aufrufen innerhalb von Skripten. - Sofern Websites nicht die Fähigkeit benötigen, Einbettungen einzuschließen, sollte deren Ausführung mit
object-src 'none'deaktiviert werden. - Wenn es Ihnen nicht möglich ist, die Verwendung von
eval()zu entfernen, können Sie das Schlüsselwortunsafe-evalzu Ihrer strikten CSP hinzufügen, um diese zu erlauben, obwohl dies die CSP erheblich schwächt. - Wenn es Ihnen nicht möglich ist, Ereignishandler-Attribute zu entfernen, können Sie das Schlüsselwort
unsafe-hasheszu Ihrer strikten CSP hinzufügen, um diese zu erlauben. Dies ist etwas unsicher, aber viel sicherer als alle Inline-JavaScript zu erlauben.
Wenn Sie es nicht schaffen, eine strikte CSP zum Funktionieren zu bringen, ist eine erlaubnisbasierte CSP viel besser als keine, und eine CSP wie default-src https: bietet trotzdem einen gewissen Schutz, indem unsicheres Inline/eval() deaktiviert wird und nur das Laden von Ressourcen (Bilder, Schriftarten, Skripte, etc.) über HTTPS erlaubt wird.
Warnung: Wenn irgendwie möglich, vermeiden Sie es, unsichere Quellen in Ihre CSP einzuschließen. Beispiele beinhalten:
unsafe-inline.data:URIs innerhalb vonscript-src,object-srcoderdefault-src.- Übermäßig breite Quellen oder Ziele für Formularübermittlungen.
Wenn Sie den Content-Security-Policy-Header nicht verwenden können, können Seiten stattdessen ein <meta http-equiv="Content-Security-Policy" content="…">-Element einschließen. Dies sollte das erste <meta>-Element sein, das im <head> des Dokuments erscheint.
Bericht-only CSPs
Bevor Sie irgendeine tatsächliche CSP mit dem Content-Security-Policy-Header implementieren, wird empfohlen, diese zuerst mit dem Content-Security-Policy-Report-Only HTTP-Header zu testen. Dies ermöglicht es Ihnen zu sehen, ob irgendwelche Verstöße mit dieser Richtlinie aufgetreten wären.
Websites sollten die Berichterstattungsrichtlinien report-to und report-uri verwenden. Diese bewirken, dass der Browser JSON-Berichte über CSP-Verstöße an Endpunkte POST, die im Reporting-Endpoints-Header im Fall von report-to angegeben sind, sendet. Dies ermöglicht es, CSP-Verstöße schnell zu erkennen und zu beheben.
Hinweis:
Die report-to-Richtlinie wird gegenüber der veralteten report-uri-Richtlinie bevorzugt. Beide sind jedoch immer noch nötig, da report-to noch keine vollständige browserübergreifende Unterstützung hat.