Content Security Policy (CSP) Implementierung
Der Content-Security-Policy HTTP-Header bietet eine feinkörnige Kontrolle darüber, welche Codes auf einer Website geladen werden können und was sie tun dürfen.
Problem
Das Hauptproblem, auf das sich dieser Artikel konzentriert, sind Cross-Site-Scripting (XSS) Angriffe. Diese resultieren in der Regel aus einem Mangel an Kontrolle und Bewusstsein für die Quellen, aus denen Seitenressourcen geladen werden. Dieses Problem wird schwieriger zu verwalten, 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 umfassenden Strategie zum Schutz vor XSS-Angriffen. Es gibt weitere Faktoren, wie Ausgabe-Codierung und Bereinigung, die ebenfalls wichtig sind.
CSP kann auch zur Lösung anderer Probleme beitragen, die in anderen Artikeln behandelt werden:
- Verhinderung von Clickjacking, indem verhindert wird, dass Ihre Seite in
<iframe>-Elemente eingebettet wird. Dies erfolgt mit der CSP-Direktiveframe-ancestors. - Verhinderung von Manipulator-in-the-Middle (MiTM) Angriffen durch Upgraden aller HTTP-Verbindungen zu HTTPS. Dies wird durch die CSP-Direktive
upgrade-insecure-requestsunterstützt. Siehe Upgrading insecure requests.
Lösung
Eine strenge CSP implementieren ist der beste Weg, um XSS-Schwachstellen mit CSP zu minimieren. Dies verwendet nonce- oder hash- basierte Fetch-Direktiven, um sicherzustellen, dass nur Skripte und/oder Stile, die das richtige Nonce oder den richtigen Hash enthalten, ausgeführt werden. Von einem Hacker eingefügtes JavaScript wird einfach nicht ausgeführt.
Strenge CSPs:
- Deaktivieren die Verwendung von unsicherem Inline-JavaScript, was bedeutet, dass 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 Objekt-Einbettungen über
object-src 'none'. - Deaktivieren die Nutzung des
<base>-Elements, um eine Basis-URI überbase-uri 'none';festzulegen.
Strenge CSPs werden gegenüber standortbasierten Richtlinien, auch Whitelist-Richtlinien genannt, bevorzugt, bei denen Sie angeben, von welchen Domains Skripte ausgeführt werden können. Dies liegt daran, dass Whitelist-Richtlinien oft dazu führen, unsichere Domains zuzulassen, was den gesamten Zweck einer CSP zunichtemacht, und diese sehr groß und unhandlich werden können, insbesondere wenn Sie versuchen, Dienste zu erlauben, die viele Drittanbieter-Skripte benötigen.
Schritte zur Implementierung von CSP
Implementieren Sie eine strenge CSP und beginnen Sie dann, Ressourcen zu identifizieren, die aufgrund der Richtlinie nicht geladen werden, und unternehmen Sie Schritte, um diese Probleme zu umgehen.
Hinweis:
Bevor Sie eine tatsächliche CSP mit dem Content-Security-Policy-Header implementieren, sollten Sie diese zunächst mit dem Content-Security-Policy-Report-Only HTTP-Header testen; siehe Report-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 strenge 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, das richtige Nonce in dienonceAttribute vom Server eingefügt haben. Wenn Sie stattdessen Hashes verwenden, sollten externe Skripte den richtigen Hash inintegrityAttribute eingefügt haben. - Wenn ein erlaubtes Skript Drittanbieter-Skripte lädt, werden diese Skripte nicht geladen, da sie nicht das erforderliche Nonce oder den erforderlichen Hash haben. Beheben Sie dieses Problem, indem Sie die
strict-dynamicDirektive hinzufügen, die Skripten, die vom ersten Skript geladen werden, dasselbe Vertrauensniveau gibt, ohne dass sie explizit ein Nonce oder einen Hash erhalten. - Überarbeiten Sie Muster, die von der strengen CSP nicht erlaubt sind, wie Inline-Event-Handler und
eval(). Ersetzen Sie zum Beispiel Inline-Event-Handler durchaddEventListener()-Aufrufe innerhalb von Skripten. - 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 dasunsafe-evalSchlüsselwort zu Ihrer strengen CSP hinzufügen, um sie zu erlauben, obwohl dies die CSP erheblich schwächer macht. - Wenn Sie Event-Handler-Attribute nicht entfernen können, können Sie das
unsafe-hashesSchlüsselwort zu Ihrer strengen CSP hinzufügen, um sie zu erlauben. Dies ist etwas unsicher, aber wesentlich sicherer als alle Inline-JavaScript zuzulassen.
Wenn Sie es nicht schaffen, eine strenge CSP zum Laufen zu bringen, ist eine Whitelist-basierte CSP viel besser als keine, und eine CSP wie default-src https: bietet dennoch einen gewissen Schutz, deaktiviert unsicheres Inline/eval() und erlaubt nur das Laden von Ressourcen (Bilder, Schriften, Skripte usw.) über HTTPS.
Warnung: Vermeiden Sie es nach Möglichkeit, unsichere Quellen in Ihre CSP aufzunehmen. Beispiele sind:
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 beinhalten. Dies sollte das erste <meta> Element sein, das im Dokument <head> erscheint.
Report-only CSPs
Bevor Sie eine tatsächliche CSP mit dem Content-Security-Policy Header implementieren, sollten Sie diese zunächst mit dem Content-Security-Policy-Report-Only HTTP Header testen. Dies ermöglicht es Ihnen zu sehen, ob Verstöße mit dieser Richtlinie aufgetreten wären.
Seiten sollten die report-to und report-uri Reporting-Direktiven verwenden. Diese veranlassen den Browser dazu, JSON-Berichte über CSP-Verstöße an Endpunkte zu POST (spezifiziert im Reporting-Endpoints Header im Fall von report-to) zu senden. Dies ermöglicht es, CSP-Verstöße schnell zu erfassen und zu beheben.
Hinweis:
Die report-to Direktive wird gegenüber der veralteten report-uri Direktive bevorzugt. Beide sind jedoch noch erforderlich, da report-to noch keine vollständige plattformübergreifende Unterstützung hat.