it-swarm.com.de

Wie funktioniert die Inhaltssicherheitsrichtlinie?

Ich erhalte eine Reihe von Fehlern in der Entwicklerkonsole:

Es wurde abgelehnt, eine Zeichenfolge zu bewerten

Die Ausführung eines Inline-Skripts wurde abgelehnt, da es gegen die folgende Richtlinie zur Inhaltssicherheit verstößt

Das Laden des Skripts wurde abgelehnt

Das Laden des Stylesheets wurde abgelehnt

Worum geht es hier? Wie funktioniert die Inhaltssicherheitsrichtlinie? Wie verwende ich den HTTP-Header Content-Security-Policy?

Insbesondere, wie man ...

  1. ... mehrere Quellen zulassen?
  2. ... unterschiedliche Richtlinien verwenden?
  3. ... mehrere Anweisungen verwenden?
  4. ... mit Ports umgehen?
  5. ... mit unterschiedlichen Protokollen umgehen?
  6. ... file:// Protokoll zulassen?
  7. ... Inline-Stile, Skripte und Tags <style> und <script> verwenden?
  8. ... eval() zulassen?

Und schlussendlich:

  1. Was genau bedeutet 'self'?
204
Schlaus

Mit dem Meta-Tag Content-Security-Policy können Sie das Risiko von XSS - Angriffen verringern, indem Sie festlegen, von wo Ressourcen geladen werden können, und so verhindern, dass Browser Daten von anderen Standorten laden. Dies erschwert es einem Angreifer, bösartigen Code in Ihre Site einzufügen.

Ich schlug meinen Kopf gegen eine Mauer, um herauszufinden, warum ich nacheinander CSP-Fehler bekam, und es schien keine genauen, klaren Anweisungen zu geben, wie das funktioniert. Hier ist also mein Versuch, einige Punkte des CSP kurz zu erklären , wobei ich mich hauptsächlich auf die Dinge konzentriere, die ich schwer lösen konnte.

Der Kürze halber schreibe ich nicht bei jedem Sample den vollständigen Tag. Stattdessen zeige ich nur die Eigenschaft content an. Ein Beispiel mit der Aufschrift content="default-src 'self'" bedeutet also Folgendes:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

1. Wie kann ich mehrere Quellen zulassen?

Sie können Ihre Quellen einfach nach einer Anweisung als durch Leerzeichen getrennte Liste auflisten:

content="default-src 'self' https://example.com/js/"

Beachten Sie, dass es keine Anführungszeichen um andere Parameter als die speziellen gibt, wie z. B. 'self'. Es gibt auch keinen Doppelpunkt (:) nach der Direktive. Nur die Direktive, dann eine durch Leerzeichen getrennte Liste von Parametern.

Alles unter den angegebenen Parametern ist implizit erlaubt. Das heißt, im obigen Beispiel wären dies gültige Quellen:

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

Diese wären jedoch nicht gültig:

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2. Wie verwende ich verschiedene Anweisungen, was machen sie jeweils?

Die gebräuchlichsten Richtlinien sind:

  • default-src die Standardrichtlinie zum Laden von Javascript, Bildern, CSS, Schriftarten, AJAX Anfragen usw
  • script-src definiert gültige Quellen für Javascript-Dateien
  • style-src definiert gültige Quellen für CSS-Dateien
  • img-src definiert gültige Quellen für Bilder
  • connect-src definiert gültige Ziele für XMLHttpRequest (AJAX), WebSockets oder EventSource. Wenn ein Verbindungsversuch zu einem Host unternommen wird, der hier nicht zulässig ist, emuliert der Browser den Fehler 400

Es gibt andere, aber diese werden Sie am ehesten brauchen.

3. Wie benutze ich mehrere Direktiven?

Sie definieren alle Ihre Anweisungen in einem Meta-Tag, indem Sie sie mit einem Semikolon (;) abschließen:

content="default-src 'self' https://example.com/js/; style-src 'self'"

4. Wie gehe ich mit Ports um?

Alles außer den Standardports muss explizit zugelassen werden, indem die Portnummer oder ein Sternchen nach der zulässigen Domäne hinzugefügt wird:

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

Das obige würde ergeben:

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

Wie bereits erwähnt, können Sie auch ein Sternchen verwenden, um alle Ports explizit zuzulassen:

content="default-src example.com:*"

5. Wie gehe ich mit verschiedenen Protokollen um?

Standardmäßig sind nur Standardprotokolle zulässig. Um beispielsweise WebSockets ws:// zuzulassen, müssen Sie dies explizit zulassen:

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

6. Wie kann ich das Dateiprotokoll file:// zulassen?

Wenn Sie versuchen, es als solches zu definieren, funktioniert es nicht. Stattdessen erlauben Sie dies mit dem Parameter filesystem:

content="default-src filesystem"

7. Wie verwende ich Inline-Skripte und Stildefinitionen?

Sofern nicht ausdrücklich erlaubt, können Sie keine Inline-Stildefinitionen, Code in <script> -Tags oder in Tag-Eigenschaften wie onclick verwenden. Du erlaubst ihnen so:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

Sie müssen auch Inline-Base64-codierte Bilder explizit zulassen:

content="img-src data:"

8. Wie kann ich eval() zulassen?

Ich bin mir sicher, dass viele Leute sagen würden, dass Sie es nicht tun, da "Eval ist böse" und die wahrscheinlichste Ursache für das bevorstehende Ende der Welt ist. Diese Leute würden sich irren. Sicher, Sie können mit eval auf jeden Fall wichtige Sicherheitslücken in Ihrer Site schließen, aber es gibt absolut gültige Anwendungsfälle. Man muss nur schlau damit umgehen. Sie erlauben es so:

content="script-src 'unsafe-eval'"

9. Was genau bedeutet 'self'?

Sie können 'self' als localhost, lokales Dateisystem oder irgendetwas auf demselben Host bezeichnen. Es bedeutet keines von denen. Dies bedeutet, dass Quellen dasselbe Schema (Protokoll), denselben Host und denselben Port wie die Datei haben, in der die Inhaltsrichtlinie definiert ist. Dann kein https für Sie, es sei denn, Sie definieren es explizit.

Ich habe 'self' in den meisten Beispielen verwendet, da es normalerweise Sinn macht, es einzuschließen, aber es ist keineswegs obligatorisch. Lass es weg, wenn du es nicht brauchst.

Aber Moment mal! Kann ich nicht einfach content="default-src *" verwenden und fertig damit sein?

Nein. Zusätzlich zu den offensichtlichen Sicherheitslücken würde dies dazu führen, dass es nicht wie erwartet funktioniert. Obwohl einige Dokumente behaupten, dass es alles erlaubt, ist das nicht wahr. Es erlaubt keine Inlinings oder Auswertungen. Um Ihre Website wirklich besonders anfällig zu machen, würden Sie Folgendes verwenden:

content="default-src * 'unsafe-inline' 'unsafe-eval'"

... aber ich vertraue dir nicht.

Weiterführende Literatur:

http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy

471
Schlaus

Apache2 MOD_HEADERS

Sie können auch Apache2 mod_headers aktivieren, unter Fedora ist es bereits standardmäßig aktiviert, wenn Sie Ubuntu/Debian verwenden und dies folgendermaßen aktivieren:

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
Apache2 -k graceful

Unter Ubuntu/Debian können Sie Header in der Datei /etc/Apache2/conf-enabled/security.conf konfigurieren.

#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"

#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"

Hinweis: Dies ist der untere Teil der Datei, nur die letzten 3 Einträge sind CSP-Einstellungen.

Der erste Parameter ist die Direktive, der zweite sind die Quellen, die auf die weiße Liste gesetzt werden sollen. Ich habe Google Analytics und einen Adserver hinzugefügt, über den Sie möglicherweise verfügen. Außerdem habe ich festgestellt, dass Sie, wenn Sie Aliase haben, z. B. www.example.com und example.com, die in Apache2 konfiguriert sind, diese ebenfalls zur Whitelist hinzufügen sollten.

Inline-Code wird als schädlich eingestuft. Sie sollten ihn vermeiden. Kopieren Sie alle Javascripts und CSS-Dateien, um sie zu trennen, und fügen Sie sie der Whitelist hinzu.

Während Sie gerade dabei sind, können Sie einen Blick auf die anderen Header-Einstellungen werfen und mod_security installieren

Weiterführende Literatur:

https://developers.google.com/web/fundamentals/security/csp/

https://www.w3.org/TR/CSP/

13
Erik Hendriks