Wie funktioniert die Inhaltssicherheitsrichtlinie?

248

Ich erhalte eine Reihe von Fehlern in der Entwicklerkonsole:

Weigerte sich, eine Zeichenfolge auszuwerten

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

Weigerte sich, das Skript zu laden

Weigerte sich, das Stylesheet zu laden

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

Insbesondere, wie man ...

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

Und schlussendlich:

  1. Was genau bedeutet 'self'das?
Schlaus
quelle

Antworten:

557

Mit dem Content-Security-PolicyMeta-Tag können Sie das Risiko von XSS- Angriffen verringern, indem Sie festlegen, wo Ressourcen geladen werden können, und verhindern, dass Browser Daten von anderen Orten laden. Dies macht es für einen Angreifer schwieriger, schädlichen 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 präzisen, klaren Anweisungen zu geben, wie das funktioniert. Hier ist mein Versuch, einige Punkte von CSP kurz zu erklären , wobei ich mich hauptsächlich auf die Dinge konzentriere, die ich schwer zu lösen fand.

Der Kürze halber werde ich nicht in jedem Beispiel das vollständige Tag schreiben. Stattdessen zeige ich nur die contentEigenschaft. Ein Beispiel mit der Aufschrift content="default-src 'self'"bedeutet Folgendes:

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

1. Wie erlaube ich mehrere Quellen?

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

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

Beachten Sie, dass es keine anderen Anführungszeichen für Parameter als die speziellen gibt, wie z 'self'. Außerdem steht :nach der Direktive kein Doppelpunkt ( ). Nur die Direktive, dann eine durch Leerzeichen getrennte Liste von Parametern.

Alles, was unter den angegebenen Parametern liegt, ist implizit zulässig. Das bedeutet, dass im obigen Beispiel dies gültige Quellen wären:

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 werden verschiedene Richtlinien verwendet, was tun sie jeweils?

Die häufigsten Richtlinien sind:

  • default-src Die Standardrichtlinie zum Laden von Javascript, Bildern, CSS, Schriftarten, AJAX-Anforderungen 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-srcDefiniert 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 einen 400Fehler

Es gibt andere, aber diese sind diejenigen, die Sie am wahrscheinlichsten brauchen.

3. Wie verwende ich mehrere Anweisungen?

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

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 führen zu:

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 erlaube ich das Dateiprotokoll file://?

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

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 verwenden onclick. Sie erlauben ihnen so:

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

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

content="img-src data:"

8. Wie erlaube ich eval()?

Ich bin sicher, dass viele Leute sagen würden, dass Sie dies nicht tun, da "Eval ist böse" und die wahrscheinlichste Ursache für das bevorstehende Ende der Welt. Diese Leute würden sich irren. Sicher, Sie können mit eval definitiv große Lücken in die Sicherheit Ihrer Site schlagen, aber es gibt absolut gültige Anwendungsfälle. Sie müssen nur klug sein, wenn Sie es verwenden. Sie erlauben es so:

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

9. Was genau bedeutet 'self'das?

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

Ich habe 'self'in den meisten Beispielen verwendet, da es normalerweise sinnvoll ist, es aufzunehmen, aber es ist keineswegs obligatorisch. Lass es weg, wenn du es nicht brauchst.

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

Nein. Zusätzlich zu den offensichtlichen Sicherheitslücken funktioniert dies nicht wie erwartet. Obwohl einige Dokumente behaupten, dass es alles erlaubt, stimmt das nicht. Inlining oder Auswertungen sind nicht zulässig. Um Ihre Website wirklich besonders anfällig zu machen, verwenden Sie Folgendes:

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

... aber ich vertraue darauf, dass du es nicht wirst.

Weiterführende Literatur:

http://content-security-policy.com

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

Schlaus
quelle
6
Guter Eintrag. Eine Sache: Es ist nicht offensichtlich, was passiert, wenn mehrere Anweisungen angegeben werden. Haben die style-src-Einstellungen in Beispiel 3 Vorrang vor default-src? etc ...
track0
29
Also, um alles alles alles zu erlauben, was der Inhalt sein würdedefault-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src * 'unsafe-inline'; frame-src *;
Arnold Roa
8
Es ist wichtig zu wissen, dass dies content="default-src * 'unsafe-inline' 'unsafe-eval'"erforderlich ist, damit einige Angular-Anwendungen funktionieren.
Flanger001
2
@ Mahesh Dieser "Blog" ist voll von Posts, die von SO kopiert wurden. Es scheint unwahrscheinlich, dass so viele SO-Benutzer Inhalte von einem unbekannten Blogger kopieren würden - ich weiß, dass ich das nicht getan habe.
Schlaus
2
Kurzer Hinweis zu connect-srcund Pfaden: Nachgestellte Schrägstriche sind obligatorisch, wenn Sie einen ganzen Unterpfad einfügen möchten. ZB: Die Datei http://foo.com/files/bar.txtwird blockiert, wenn die Quelle ist http://foo.com/files, aber http://foo.com/files/
bereitgestellt
15

APACHE2 MOD_HEADERS

Sie können auch Apache2 mod_headers aktivieren. Unter Fedora ist es bereits standardmäßig aktiviert. Wenn Sie Ubuntu / Debian verwenden, aktivieren Sie es wie folgt:

# 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 konfigurieren /etc/apache2/conf-enabled/security.conf

#
# 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 drei 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, den Sie möglicherweise haben. Außerdem habe ich festgestellt, dass Sie Aliase, z. B. www.example.com und example.com, die in Apache2 konfiguriert sind, ebenfalls zur Whitelist hinzufügen sollten.

Inline-Code wird als schädlich angesehen. Sie sollten ihn vermeiden. Kopieren Sie alle Javascripts und CSS in separate Dateien und fügen Sie sie der Whitelist hinzu.

Während Sie gerade dabei sind, können Sie sich die anderen Header-Einstellungen ansehen und mod_security installieren

Weiterführende Literatur:

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

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

Erik Hendriks
quelle
2
Ich konnte meiner .htaccess-Datei dieselben Anweisungen hinzufügen, da ich Apache-Konfigurationen auf meinem freigegebenen Host nicht bearbeiten kann. Unter report-uri.io/home/tools habe ich hervorragende Tools zum Anpassen dieser Einstellungen gefunden .
Michael McGinnis
Gibt es eine Möglichkeit, dieses Problem mit Tomcat 7 zu beheben? Ich habe versucht, Filter hinzuzufügen, und es hat nicht funktioniert.
Elshan
0

Vergessen Sie nicht, dass font-src genauso funktioniert wie alle anderen. Wenn Sie jedoch Schriftarten verwenden, die von anderen Ursprüngen geladen wurden, stellen Sie sicher, dass Sie sie dem Meta-Tag hinzufügen

Mikhail Andrianov
quelle