Implementierung der Content Security Policy (CSP)
Der HTTP-Header Content-Security-Policy
bietet eine detaillierte Kontrolle über den Code, der auf einer Website geladen werden kann, und über das, was er tun darf.
Problem
Das Hauptproblem, auf das sich dieser Artikel konzentriert, sind Cross-Site-Scripting- (XSS) Angriffe. Diese sind im Allgemeinen auf einen Mangel an Kontrolle und Bewusstsein über die Quellen zurückzuführen, aus denen Ressourcen einer Website geladen werden. Dieses Problem wird schwieriger zu verwalten, wenn Websites größer und komplexer werden und zunehmend auf Drittanbieterressourcen wie JavaScript-Bibliotheken angewiesen sind.
Hinweis: CSP ist ein Teil einer umfassenden Strategie zum Schutz vor XSS-Angriffen. Es gibt auch andere wichtige Faktoren, wie Output Encoding und Sanitization.
CSP kann auch helfen, andere Probleme zu beheben, die in anderen Artikeln behandelt werden:
- Verhinderung von Clickjacking durch das Verhindern des Einbettens Ihrer Website in
<iframe>
-Elemente. Dies erfolgt durch die CSP-Direktiveframe-ancestors
. - Verhinderung von Manipulator-in-the-Middle-Angriffen (MiTM) durch das Upgrade aller HTTP-Verbindungen auf HTTPS. Dies wird durch die CSP-Direktive
upgrade-insecure-requests
unterstützt. Siehe Upgrade unsicherer Anfragen.
Lösung
Die Implementierung einer strikten CSP ist der beste Weg, um XSS-Sicherheitslücken mit CSP zu minimieren. Dies nutzt auf nonce-
oder hash-
basierende Fetch-Direktiven, um sicherzustellen, dass nur Skripte und/oder Styles ausgeführt werden, die den richtigen Nonce oder Hash enthalten. Von Hackern eingefügtes JavaScript wird einfach nicht ausgeführt.
Strikte CSPs:
- Deaktivieren die Nutzung von unsicherem Inline-JavaScript, was inline Ereignis-Handler-Attribute wie
onclick
bedeutet. Dadurch wird verhindert, dass falsch maskierte Benutzereingaben vom Webbrowser als JavaScript interpretiert werden. - Deaktivieren die Nutzung 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, um eine Basis-URI festzulegen, überbase-uri 'none';
.
Strikte CSPs sind gegenüber standortbasierten Richtlinien vorzuziehen, die auch als Whitelist-Richtlinien bezeichnet werden, bei denen Sie angeben, von welchen Domains Skripte ausgeführt werden können. Dies liegt daran, dass Whitelist-Richtlinien oft unsichere Domains zulassen, was den gesamten Zweck einer CSP untergräbt, und sie können sehr groß und unhandlich werden, insbesondere wenn Sie versuchen, Dienste zu erlauben, die viele Drittanbieter-Skripte benötigen.
Schritte zur Implementierung einer CSP
Implementieren Sie eine strikte CSP und beginnen Sie dann, Ressourcen zu identifizieren, die aufgrund der Richtlinie nicht geladen werden, 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, diese 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 strikte CSP, wie im Abschnitt Lösung beschrieben. Stellen Sie sicher, dass externe und interne Skripte (eingebunden über
<script>
-Elemente), die Sie ausführen möchten, den richtigen Nonce in den vom Server eingefügtennonce
-Attributen haben. Wenn Sie stattdessen Hashes verwenden, sollten externe Skripte den richtigen Hash in denintegrity
-Attributen haben. - Wenn ein erlaubtes Skript dazu übergeht, Drittanbieter-Skripte zu laden, werden diese Skripte nicht geladen, da sie nicht den erforderlichen Nonce oder Hash haben. Umgehen Sie dieses Problem, indem Sie die Direktive
strict-dynamic
hinzufügen, die Skripten, die vom ersten Skript geladen werden, dasselbe Maß an Vertrauen gibt, ohne dass ihnen explizit ein Nonce oder Hash gegeben werden muss. - Refaktorieren Sie Muster, die von der strikten CSP nicht erlaubt sind, wie Inline-Ereignis-Handler und
eval()
. Beispielsweise können Sie Inline-Ereignis-Handler durch Aufrufe vonaddEventListener()
in Skripten ersetzen. - Sofern Websites nicht die Möglichkeit benötigen, Einbettungen einzuschließen, sollte deren Ausführung mit
object-src 'none'
deaktiviert werden. - Wenn Sie die Verwendung von
eval()
nicht entfernen können, können Sie das Schlüsselwortunsafe-eval
Ihrer strikten CSP hinzufügen, um sie zu erlauben, obwohl dies die CSP erheblich schwächt. - Wenn Sie Ereignis-Handler-Attribute nicht entfernen können, können Sie das Schlüsselwort
unsafe-hashes
Ihrer strikten CSP hinzufügen, um sie zu erlauben. Dies ist etwas unsicher, aber wesentlich sicherer als die Erlaubnis aller Inline-JavaScripts.
Wenn Sie eine strikte CSP nicht zum Laufen bringen können, ist eine auf Whitelists basierende CSP viel besser als keine, und eine CSP wie default-src https:
bietet immer noch einen gewissen Schutz, indem unsicheres Inline- und eval()
deaktiviert wird und nur das Laden von Ressourcen (Bilder, Schriftarten, Skripte usw.) über HTTPS erlaubt wird.
Warnung: Vermeiden Sie, wenn irgend möglich, das Einbinden unsicherer Quellen in Ihre CSP. Beispiele sind:
unsafe-inline
.data:
-URIs innerhalb vonscript-src
,object-src
oderdefault-src
.- zu breite Quellen oder Zielorte für Formularübermittlungen.
Ebenso kann die Verwendung von script-src 'self'
für Websites mit JSONP-Endpunkten unsicher sein. Diese Websites sollten ein script-src
verwenden, das den Pfad zu ihren JavaScript-Quellordnern enthält.
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 innerhalb des Dokuments im <head>
erscheint.
Nur-Bericht-CSPs
Bevor Sie eine 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 Verstöße gegen diese Richtlinie aufgetreten wären.
Websites sollten die Reporting-Direktiven report-to
und report-uri
verwenden. Diese bewirken, dass der Browser JSON-Berichte über CSP-Verstöße an Endpunkte sendet (spezifiziert im Reporting-Endpoints
-Header im Falle von report-to
). Dies ermöglicht es, CSP-Verstöße schnell zu erkennen und zu beheben.
Hinweis:
Die Direktive report-to
wird gegenüber der veralteten Direktive report-uri
bevorzugt. Beide werden jedoch noch benötigt, da report-to
noch keine vollständige Unterstützung über alle Browser hinweg hat.