Implementierung der Content Security Policy (CSP)
Der Content-Security-Policy
HTTP-Header bietet eine feingranulare Kontrolle über den Code, der auf einer Website geladen werden kann, und was er tun darf.
Problem
Das Hauptproblem, auf das sich dieser Artikel konzentriert, sind Cross-Site-Scripting (XSS) Angriffe. Diese resultieren im Allgemeinen aus einem Mangel an Kontrolle und Bewusstsein über die Quellen, aus denen Webseitenressourcen geladen werden. Dieses Problem wird schwieriger zu handhaben, je größer und komplexer Websites werden und je mehr sie auf Drittanbieter-Ressourcen wie JavaScript-Bibliotheken angewiesen sind.
Hinweis: CSP ist ein Teil einer vollständigen Strategie zum Schutz vor XSS-Angriffen. Es gibt 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 das Einbetten Ihrer Seite in
<iframe>
-Elemente verhindert wird. Dies wird durch die CSP-Direktiveframe-ancestors
erreicht. - Verhindern von Manipulator-in-the-Middle (MiTM) Angriffen, indem alle HTTP-Verbindungen auf HTTPS aufgerüstet werden. Dies wird durch die CSP-Direktive
upgrade-insecure-requests
unterstützt. Siehe Aufrüsten unsicherer Anfragen.
Lösung
Die Implementierung einer strengen CSP ist der beste Weg, um XSS-Schwachstellen mit CSP zu mindern. Diese verwendet Nonce- oder Hash-basierte Fetch-Direktiven, um sicherzustellen, dass nur Skripte und/oder Stile ausgeführt werden, die den korrekten Nonce oder Hash enthalten. JavaScript, das von einem Hacker eingefügt wurde, wird einfach nicht ausgeführt.
Strenge CSPs:
- Deaktivieren die Verwendung von unsicherem inline JavaScript, was bedeutet, dass inline Event-Handler Attribute wie
onclick
deaktiviert sind. Dies verhindert, dass unsachgemäß kodierte Benutzereingaben vom Webbrowser als JavaScript interpretiert werden. - Deaktivieren die Verwendung von riskanten API-Aufrufen wie
eval()
, was ein weiterer Effekt derscript-src
-Direktive ist. - Deaktivieren alle Objekteinbettungen über
object-src 'none'
. - Deaktivieren die Verwendung des
<base>
-Elements zur Festlegung eines Basis-URI überbase-uri 'none';
.
Strenge CSPs werden bevorzugt gegenüber standortbasierten Richtlinien, auch als Whitelist-Richtlinien bezeichnet, bei denen Sie angeben, von welchen Domains Skripte ausgeführt werden können. Dies liegt daran, dass Whitelist-Richtlinien oft am Ende unsichere Domains zulassen, was den gesamten Zweck einer CSP zunichte macht, und sie können sehr groß und unhandlich werden, besonders wenn Sie versuchen, Dienste zuzulassen, die viele Drittanbieterskripte erfordern.
Schritte zur Implementierung der CSP
Implementieren Sie eine strenge CSP und beginnen Sie dann damit, Ressourcen zu identifizieren, die infolge der Richtlinie nicht geladen werden können, und ergreifen Sie Maßnahmen, um diese Probleme zu umgehen.
Hinweis:
Bevor Sie eine tatsächliche CSP mit dem Content-Security-Policy
-Header implementieren, wird empfohlen, es zuerst mit dem Content-Security-Policy-Report-Only
HTTP-Header zu testen; siehe Nur-Bericht-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 strenge CSP, wie im Abschnitt Lösung beschrieben. Stellen Sie sicher, dass externe und interne Skripte (eingefügt über
<script>
-Elemente), die Sie ausführen möchten, den korrekten Nonce in dienonce
Attribute durch den Server eingefügt haben. Wenn Sie stattdessen Hashes verwenden, sollten externe Skripte den korrekten Hash in dieintegrity
Attribute eingefügt haben. - Wenn ein erlaubtes Skript andere Drittanbieterskripte lädt, können diese Skripte nicht geladen werden, da sie nicht den erforderlichen Nonce oder Hash haben. Mildern Sie dieses Problem, indem Sie die
strict-dynamic
Direktive hinzufügen, die geladene Skripte des ersten Skripts auf demselben Vertrauensniveau hält, ohne explizit ein Nonce oder Hash zugewiesen zu bekommen. - Überarbeiten Sie Muster, die durch die strenge CSP untersagt sind, wie Inline-Event-Handler und
eval()
. Zum Beispiel ersetzen Sie Inline-Event-Handler durchaddEventListener()
Aufrufe innerhalb von Skripten. - Sofern Websites nicht die Möglichkeit benötigen, Einbettungen zu verwenden, sollte deren Ausführung mit
object-src 'none'
deaktiviert werden. - Wenn Sie nicht in der Lage sind, die Verwendung von
eval()
zu entfernen, können Sie dasunsafe-eval
Schlüsselwort zu Ihrer strengen CSP hinzufügen, um sie zu erlauben, obwohl dies die CSP erheblich schwächer macht. - Wenn Sie nicht in der Lage sind, Ereignis-Handler-Attribute zu entfernen, können Sie das
unsafe-hashes
Schlüsselwort zu Ihrer strengen CSP hinzufügen, um sie zu erlauben. Dies ist zwar etwas unsicher, aber viel sicherer, als alle Inline-JavaScript zuzulassen.
Wenn Sie es nicht schaffen, eine strenge CSP zu implementieren, ist eine Whitelist-basierte CSP viel besser als keine, und eine CSP wie default-src https:
bietet immer noch einen gewissen Schutz, indem sie unsicheres Inline/eval()
deaktiviert und nur das Laden von Ressourcen (Bilder, Schriftarten, Skripte usw.) über HTTPS zulässt.
Warnung: Wenn es überhaupt möglich ist, vermeiden Sie, unsichere Quellen in Ihre CSP aufzunehmen. Beispiele hierfür sind:
unsafe-inline
.data:
URIs inscript-src
,object-src
oderdefault-src
.- Zu breite Quellen oder Einreichungsziele von Formularen.
Wenn Sie den Content-Security-Policy
-Header nicht verwenden können, können Seiten stattdessen ein <meta http-equiv="Content-Security-Policy" content="…">
Element einfügen. Dies sollte das erste <meta>
Element sein, das im Dokument <head>
erscheint.
Nur-Bericht-CSPs
Bevor Sie eine tatsächliche CSP mit dem Content-Security-Policy
-Header implementieren, wird empfohlen, sie zuerst mit dem Content-Security-Policy-Report-Only
HTTP-Header zu testen. Dies erlaubt Ihnen zu sehen, ob Verstöße mit dieser Richtlinie aufgetreten wären.
Websites sollten die Berichts-Direktiven report-to
und report-uri
verwenden. Diese veranlassen den Browser, JSON-Berichte über CSP-Verstöße an Endpunkte zu POST
en (angegeben im Reporting-Endpoints
Header im Fall von report-to
). Dadurch können CSP-Verstöße schnell erfasst und behoben werden.
Hinweis:
Die report-to
Direktive wird über die veraltete report-uri
Direktive bevorzugt. Beide sind jedoch noch erforderlich, da report-to
noch keinen vollständigen Cross-Browser-Support hat.