Content Security Policy: Schutz vor Cross-Site-Scripting

Philipp Zeder
Autor:

Philipp Zeder

Kategorie:

in

Entwicklung & Performance

Veröffentlicht am 9. März 2016

Aktualisiert am 9. Mai 2022

Mithilfe von Cross-Site-Scripting (XSS) lässt sich Böses mit einer Website anstellen. Eine ganze Menge Massnahmen helfen, XSS auf der eigenen Website zu verhindern. Eine dieser Möglichkeiten nennt sich Content Security Policy (CSP). Wir zeigen heute, was CSP ist, wie Sie für Ihre Website eine Policy definieren können und welche Stolperfallen lauern.

Helm auf! Eine Content Security Policy schützt vor Cross-Site-Scripting

Helm auf! Eine Content Security Policy schützt vor Cross-Site-Scripting

Wie es zur Content Security Policy kam

Content Security Policy (CSP) ist ein Konzept, um das Einschleusen von fremden Daten auf einer Website zu verhindern. Damals noch unter dem Namen «Content Restrictions» wurde das Konzept im Jahr 2004 erstmals von Robert Hansen vorgeschlagen. Als erster Browser unterstützte Firefox 4 die Content Security Policy, andere Browserhersteller zogen bald nach. Im Jahr 2012 wurde dann die erste Version, Content Security Policy 1.0 genannt, als «Candidate Recommendation» vom W3C publiziert. Mittlerweile wird bereits an der dritten Version, der Content Security Policy Level 3, gearbeitet.

So give it another year or so and we should have a workable defense against XSS on pages that must allow user submitted HTML and JavaScript – think eBay, MySpace, and so on.

— Quelle: ha.ckers.org via archive.org

War zu den Anfägen von CSP das Problem Cross-Site-Scripting noch ein Ding von Anbietern wie eBay oder MySpace, ist heutzutage praktisch jede Website potentiell anfällig auf Cross-Site-Scripting. Mit einer Content Security Policy lässt sich sehr genau definieren, aus welchen Quellen Inhalte geladen werden dürfen. Das schafft Sicherheit, führt früher oder später aber in eine Zwickmühle, wie sich gleich zeigen wird.

Wie definiere ich eine Content Security Policy?

Die CSP einer Website wird vorzugsweise im HTTP-Header definiert, kann aber auch als Meta-Tag direkt im Markup hinterlegt sein. Die Meta-Tag-Methode eignet sich vor allem für einzelne Seiten, für die spezielle Regeln gelten sollen. In unseren Beispielen wählen wir die HTTP-Header-Methode, die sich dank mod_headers bequem über die .htaccess-Datei steuern lässt. Alternativ können HTTP-Header auch direkt mithilfe von PHP-Code definiert werden.

Eine simple Content Security Policy liesse sich zum Beispiel mit folgender Anweisung in der .htaccess-Datei definieren:

Header set Content-Security-Policy "default-src 'self';"

Mit dieser CSP sind auf der entsprechenden Website nur noch Inhalte erlaubt, die auch über die aufgerufene Domain geladen werden. Externe und Inline-Scripts werden so verboten. Nutzen Sie auf Ihrer Website Scripts wie Google Analytics oder haben mit <script> im HTML-Markup Funktionen definiert, würden diese mit der gesetzten Policy nicht mehr funktionieren. Eine Lockerung der Regeln muss also her.

Mit

Header set Content-Security-Policy "default-src 'self' www.google-analytics.com;"

erlauben Sie zusätzlich zur eigenen Domain Inhalte, die über den Hostnamen www.google-analytics.com eingebunden sind.

Google Analytics generiert selbst Inline-Scripts. Erweitern wir die Regel noch mit 'unsafe-inline' sind auch Inline-Inhalte wieder erlaubt:

Header set Content-Security-Policy "default-src 'self' 'unsafe-inline' cdn.example.com;"

Aber Achtung: Der Befehl 'unsafe-inline' hebelt den Hauptnutzen einer Content Security Policy aus. Damit ist nämlich das Einschleusen von Code, also Cross-Site-Scripting, wieder möglich. Und hier beginnt die oben erwähnte Zwickmühle, denn Tools wie Google Analytics funktionieren nur, wenn Inline-Scripts erlaubt sind. In vielen Fällen kann man damit das Thema CSP bereits abhaken.

Doch nicht nur Inline-Scripts machen in Verbindung mit einer Content Security Policy Probleme. Viele Scripts wie z.B. Widgets von Facebook oder Twitter sind darauf angewiesen, dass Code aus Drittquellen geladen werden darf. Die Adressen dieser Quellen müssen wiederum in der eigenen Policy freigeschaltet sein, damit der Browser den angeforderten Code zulässt. Da sich diese Hostnamen aber immer wieder einmal ändern und die Anbieter nur selten alle eingesetzten Adressen kommunizieren, wird eine strikte Content Security Policy früher oder später dazu führen, dass eingebundene Scripts nicht mehr wie gewünscht funktionieren. Im schlimmsten Fall wird eine Website damit unbenutzbar.

Zwischenschritt Reporting

Sie sehen, eine sinnvolle Content Security Policy benötigt etwas Arbeit. Es empfiehlt sich, die geplanten Regeln ausführlich zu testen, bevor sie im Livebetrieb eingesetzt werden. Zum Glück liefert CSP eine dazu passende Funktion mit. Mit Content-Security-Policy-Report-Only ahndet der Browser allfällige Policy-Verstösse nicht, sondern gibt entsprechende Fehlermeldungen in der Browserkonsole aus. So liesse sich also mit der Regel

Header set Content-Security-Policy-Report-Only "default-src 'self' 'unsafe-inline' cdn.example.com;"

die geplante Policy zuerst einmal auf Herz und Nieren prüfen.

CSP-Verstosse werden in der Browserkonsole angezeigt.

CSP-Verstosse werden in der Browserkonsole angezeigt.

Content-Security-Policy-Report-Only kann nicht nur Meldungen im Browser ausgeben, sondern auch Policy-Verstösse im JSON-Format an einen Endpunkt melden. Wer sich nicht die Mühe machen will, einen eigenen Endpunkt zu programmieren, findet unter report-uri.io einen tollen, kostenlosen Service, der nebst anderen praktischen Tools zum Thema CSP einen solchen Reporting-Endpunkt zur Verfügung stellt.

Einmal Upgrade bitte

Seit verschlüsselte Verbindungen zunehmend zum Standard werden, rückt eine CSP-Direktive ins Scheinwerferlicht. Mit upgrade-insecure-requests lassen sich unsichere, über HTTP eingebundene Quellen automatisch auf die sichere Variante HTTPS upgraden. Wird mit Header set Content-Security-Policy "upgrade-insecure-requests;" die Direktive gesetzt, lädt der Browser sämtliche Inhalte über HTTPS, selbst wenn diese «nur» über HTTP eingebunden sind. Zurzeit unterstützen Chrome, Firefox und Opera diese Funktion. IE-, Edge- und Safari-Nutzer bleiben vorerst aussen vor.

Browserunterstützung von upgrade-insecure-requests

Browserunterstützung von «upgrade-insecure-requests». Quelle: caniuse.com

Sicherheit für Besucher

Eine ausgeklügelte Content Security Policy bietet umfassende Möglichkeiten, Besucher Ihrer Website vor bösen Angriffen zu schützen. Sie schützt jedoch nicht, wenn Angreifer Zugriff auf Ihr Webhosting erlangen. Die CSP ersetzt also nicht die Pflege des eingesetzten Content-Management-Systems und das Schliessen von allfälligen Sicherheitslücken.

Möchten Sie eine Content Security Policy für Ihre Website implementieren? Im Netz finden Sie viel interessante Lektüre dazu. Als Startpunkt empfehlen wir die Website content-security-policy.com, das Mozilla Developer Network (MDN), html5rocks.com oder diesen Blogbeitrag von Diogo Mónica.

Beteilige dich an der Diskussion

8 Kommentare

Markus
Markus 27. März 2016 00:42

Danke, die Information über mod_headers war sehr nützlich für mich.

Rolf Tschaeppeler
Rolf Tschaeppeler 23. März 2016 23:20

Danke für den interessanten Artikel.

Für Drupal-Siteadmins gibt es ein interessantes Modul, das viele der besprochenen Konfigurationen unterstützt (u.a. das Reporting).
Hier der Link: https://www.drupal.org/project/seckit

Gruss, Rolf

Philipp Zeder
Philipp Zeder cyon
24. März 2016 10:22

Vielen Dank für den Tipp, Rolf.

NetHawk
NetHawk 23. März 2016 17:13

Grosses Kompliment an Euch für die wertvollen, praxisnahen Beiträge.

Philipp Zeder
Philipp Zeder cyon
23. März 2016 17:45

Herzlichen Dank :)

E-CommerceAgentur.ch
E-CommerceAgentur.ch 14. März 2016 19:31

Super Sache.
Sowohl der Blogbeitrag bzw-beiträge als auch solche technischen Möglichkeiten.

Leider dem breiten Publikum noch zu wenig bekannt.

Simon
Simon 9. März 2016 18:04

Wie immer, grossartige Blogbeiträge mit Tiefgang.

Philipp Zeder
Philipp Zeder cyon
10. März 2016 11:51

Herzlichen Dank Simon ?