Inhaltssicherheitsrichtlinie (CSP) Implementierung
Der Content-Security-Policy HTTP-Header bietet eine fein abgestimmte Kontrolle darüber, welcher Code auf einer Seite geladen werden kann und was er tun darf.
Problem
Das Hauptproblem, auf das sich dieser Artikel konzentriert, sind Cross-Site Scripting (XSS) Angriffe. Diese entstehen in der Regel durch fehlende Kontrolle und Unkenntnis über die Quellen, von denen Seitenressourcen geladen werden. Dieses Problem wird schwieriger zu handhaben, je größer und komplexer Websites werden und je stärker sie auf Ressourcen Dritter 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 z.B. Output-Encoding und Sanitization.
CSP kann auch helfen, andere Probleme zu lösen, die in anderen Artikeln behandelt werden:
- Verhinderung von Clickjacking, indem verhindert wird, dass Ihre Seite in
<iframe>-Elemente eingebettet wird. Dies wird mit der CSP-Direktiveframe-ancestorserreicht. - Verhinderung von Man-in-the-Middle (MiTM) Angriffen durch Hochstufen von HTTP-Verbindungen auf HTTPS. Dies wird durch die CSP-Direktive
upgrade-insecure-requestsunterstützt. Siehe Veraltete unsichere Anforderungen hochstufen.
Lösung
Die Implementierung einer strengen CSP ist der beste Weg, um XSS-Schwachstellen mit CSP zu begegnen. Dabei werden nonce- oder hash-basierte Lade-Direktiven verwendet, um sicherzustellen, dass nur Scripts und/oder Styles ausgeführt werden, die den richtigen Nonce oder Hash enthalten. Von einem Hacker eingefügtes JavaScript wird einfach nicht ausgeführt.
Strenge CSPs:
- Deaktivieren die Verwendung unsicheren Inline-JavaScripts, wie Inline Ereignis-Handler-Attribute wie
onclick. Dies verhindert, dass unsachgemäß escapte 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 zur Festlegung einer Basis-URI überbase-uri 'none';.
Strenge CSPs sind bevorzugt gegenüber standortbasierten Richtlinien, auch als Positivlisten-Richtlinien bekannt, bei denen Sie festlegen, von welchen Domains Skripte ausgeführt werden dürfen. Das liegt daran, dass Positivlisten-Richtlinien oft dazu führen, dass unsichere Domains erlaubt werden, was den gesamten Sinn einer CSP zunichte macht, und sie können sehr groß und unübersichtlich werden, insbesondere wenn Sie versuchen, Dienste zuzulassen, die viele Drittanbieter-Skripte zum Funktionieren benötigen.
Schritte zur Implementierung der CSP
Implementieren Sie eine strenge CSP und beginnen Sie, Ressourcen zu identifizieren, die aufgrund der Richtlinie nicht geladen werden können. Unternehmen Sie Schritte, um diese Probleme zu umgehen.
Hinweis:
Bevor Sie irgendeine 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; 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 richtigen Nonce in dennonceAttributen durch den Server eingefügt haben. Wenn Sie stattdessen Hashes verwenden, sollten externe Skripte den richtigen Hash in denintegrityAttributen haben. - Wenn ein erlaubtes Skript weitere Drittanbieter-Skripte lädt, werden diese Skripte nicht geladen, da sie den erforderlichen Nonce oder Hash nicht haben. Beheben Sie dieses Problem, indem Sie die
strict-dynamicDirektive hinzufügen, die Skripten, die vom ersten Skript geladen werden, das gleiche Vertrauensniveau gibt, ohne ihnen explizit einen Nonce oder Hash zu geben. - Überarbeiten Sie Muster, die von der strengen CSP nicht zugelassen werden, wie Inline-Ereignis-Handler und
eval(). Ersetzen Sie beispielsweise Inline-Ereignis-Handler durchaddEventListener()-Aufrufe innerhalb von Skripten. - Sofern Websites nicht die Möglichkeit benötigen, Einbettungen zu enthalten, sollte deren Ausführung mit
object-src 'none'deaktiviert werden. - Wenn Sie die Verwendung von
eval()nicht entfernen können, können Sie dasunsafe-evalSchlüsselwort zu Ihrer strengen CSP hinzufügen, um sie zuzulassen, obwohl dies die CSP erheblich schwächt. - Wenn Sie die Verwendung von Ereignis-Handler-Attributen nicht entfernen können, können Sie das
unsafe-hashesSchlüsselwort zu Ihrer strengen CSP hinzufügen, um sie zuzulassen. Dies ist etwas unsicher, aber viel sicherer als die Erlaubnis aller Inline-JavaScripts.
Wenn Sie keine strenge CSP zum Laufen bringen können, ist eine Positivlisten-basierte CSP viel besser als keine, und eine CSP wie default-src https: bietet dennoch einen gewissen Schutz, indem unsichere Inline-/eval()-Ausführungen deaktiviert werden und nur das Laden von Ressourcen (Bilder, Schriften, Skripte usw.) über HTTPS erlaubt wird.
Warnung: Wenn möglich, vermeiden Sie es, unsichere Quellen in Ihrer CSP aufzunehmen. Beispiele beinhalten:
unsafe-inline.data:URIs innerhalb vonscript-src,object-srcoderdefault-src.- Zu breite Quellen oder Zieladressen für Formulareinsendungen.
Falls 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 Dokument <head> erscheint.
Nur-Bericht CSPs
Bevor Sie irgendeine 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. Auf diese Weise können Sie sehen, ob mit dieser Richtlinie Verstöße 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 POSTen (wie im Reporting-Endpoints Header im Fall von report-to angegeben). Dadurch können CSP-Verstöße schnell erkannt und behoben werden.
Hinweis:
Die report-to Direktive wird der veralteten report-uri Direktive vorgezogen. Beide sind jedoch weiterhin erforderlich, da report-to noch keine vollständige browserübergreifende Unterstützung hat.