Sicherheit/Content Security Policy

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Die Hersteller der Browser und auch die Webstandards entwickelnden Gremien sind ständig darum bemüht, Mechanismen zu finden, mit denen Angriffe auf Seitenbesucher verhindert werden können. Es geht insbesondere darum, das Unterschieben von bösartigem Code abzuwehren. Bei den sogenannten Cross-Site-Scripting-Attacken werden Daten von fremden Webservern eingebunden, die die Aufgabe haben, den Datenverkehr auf der gerade besuchten Website auszuspionieren, diesen zu manipulieren oder gar mögliche Softwarefehler auf dem Rechner des Seitenbesuchers auszunutzen, um Schadsoftware zu installieren.

Ein solcher Abwehrmechanismus ist die Content Security Policy (zu deutsch etwa „Richtlinie für die Sicherheit der Inhalte“). Die Idee dahinter ist, dass der Webserver beim Ausliefern der eigentlichen Webseite noch zusätzliche Meta-Daten übermittelt, die den Browser dazu veranlassen, verschiedene Vorgänge zu verhindern. So ist es damit beispielsweise möglich, dass der Browser keine JavaScript-Dateien lädt und ausführt, wenn diese nicht von exakt demselben Webserver stammen, von dem die eigentliche Seite geladen wurde. Es kann sehr fein abgestuft werden, ob das JavaScript in einer eigenen Datei notiert sein muss, oder ob direkt im HTML-Dokument notierter JavaScript-Code, der in <script>-Elemente eingebettet ist, ausgeführt werden darf.

Beachten Sie: Es gibt mehrere Versionen: CSP (veraltet), CSP2 (aktuell), CSP3 (in Entwicklung). Stand: 2022

Der CSP-Header

Beim Ausliefern des HTML-Dokuments bedarf es eines speziellen HTTP-Headers, der den Browser die Content Security Policy anwenden lässt. Dazu gibt es mehrere Möglichkeiten:

  • <meta>-Element im HTML-Code
  • serverseitige Scriptsprache
  • Konfiguration des Webservers

Historisch

Vor der vollständigen Unterstützung nutzten Browser die experimentellen Header:

  • Internet Explorer und Firefox X-Content-Security-Policy
  • Chrome und Safari X-WebKit-CSP

Diese Browser unterstützen seit 2013 den standardisierten Header bzw. sind nicht mehr auf dem Markt. Sie können daher in Ihrer Website auf die experimentellen Header verzichten.

<meta>-Element im HTML-Code

Wenn kein CSP-Header vom Server versandt wird, kann man mit einem passenden <meta>-Element nachhelfen. Sollte der Server irgendwann doch einen CSP-Header senden, hat dieser – wie in solchen Fällen üblich – für den Browser Vorrang vor dem <meta>-Element.

<meta>-Element im HTML-Code
<!doctype html>
<head>
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  <title>CSP nutzende Seite</title>
</head>
<body>
  <h1>Sie sind sicher</h1>
  <p>Dieses Dokument wurde mit einer sehr strikt eingestellten Content Security Policy ausgeliefert.</p>
</body>
</html>
Im Kopf des Dokuments ist ein <meta>-Element notiert, welches den Browser erkennen lässt, dass er das Sicherheitskonzept anwenden soll. Die Anweisung default-src 'self' bedeutet, dass er prinzipiell nur zusätzliche Inhalte laden darf, wenn sie vom selben Server stammen. Die Anweisung script-src 'self' im content-Attribut erklärt dem Browser, dass er nur JavaScript-Dateien laden darf, die vom selben Server stammen wie dieses Dokument.
Diese Direktive hat eine zusätzliche Auswirkung: Der Browser darf keinen JavaScript-Code ausführen, der im HTML-Dokument selbst notiert ist. Soll JavaScript ausgeführt werden, so muss es in einer separaten Datei notiert stehen.

serverseitige Scriptsprache

CSP mit einfachsten Mitteln in PHP
<?php
header("Content-Security-Policy: default-src 'self'; script-src 'self'");
Das Beispiel nutzt die PHP-interne Funktion header(), um einen HTTP-Header an den Browser zu senden.

Konfiguration des Webservers

Wenn man seinen eigenen Webserver konfigurieren kann, was bei günstigen Hostingangeboten in aller Regel nicht der Fall ist, dann gibt es diese Einstellungsmöglichkeit:

Beispiel
Header set Content-Security-Policy "default-src 'self';"
Beispiel
server {
  ...
  add_header Content-Security-Policy "default-src 'self';";
}

Einstellungsmöglichkeiten

Die CSP bringt eine ganze Reihe an Parametern mit, mit denen sich das Browserverhalten sehr fein einstellen lässt.

Direktive Beispielwert Erläuterung
default-src 'self' cdn.example.com Die Direktive default-src ist die Voreinstellung für alle Richtlinien, die weitere Inhalte nachladen wie z. B. JavaScript, Bilder, CSS, Schriftarten, AJAX Requests, Frames und HTML5 Medien. In der Referenz der Werteangaben steht genaueres über die möglichen Werte, die Sie hier anstelle von 'self' verwenden können.
script-src 'self' js.example.com Definiert erlaubte Quellen für JavaScript.
style-src 'self' css.example.com Definiert erlaubte Quellen für Stylesheets.
img-src 'self' img.example.com Definiert erlaubte Quellen für Bilder.
connect-src 'self' Gilt für XMLHttpRequests (AJAX), WebSockets oder EventSource. Wenn solche Inhalte nicht erlaubt sein sollen, wird der Browser beim Laden der Seite einen 400 HTTP Status Code emulieren.
font-src font.example.com Definiert erlaubte Quellen für Schriftarten.
object-src 'self' Definiert erlaubte Quellen für Plugins, z. B. <object>, <embed> oder <applet>.
media-src media.example.com Definiert erlaubte Quellen für Audio und Video, z. B. HTML5 <audio>, <video> Elemente.
sandbox allow-forms allow-scripts Ermöglicht einen Sandbox-Betrieb für die angeforderte Ressource, ähnlich wie <iframe sandbox>. Im Sandbox-Betrieb gilt eine Same-Origin-Policy, Popups werden verhindert und Plugins und das Ausführen von JavaScript werden blockiert. Sie können den Wert für sandbox leer lassen, um alle Einschränkungen zu belassen, oder Sie fügen eine dieser Wertegruppen hinzu: allow-forms allow-same-origin allow-scripts allow-popups, allow-modals, allow-orientation-lock, allow-pointer-lock, allow-presentation, allow-popups-to-escape-sandbox, und allow-top-navigation
report-uri /pfad-zu-server-script Diese Direktive weist den Browser an, Berichte über an Richtlinien gescheiterte Vorgänge mittels der POST-Methode an die angegebene Adresse zu senden. Sie können den Zusatz -Report-Only an den HTTP-Headernamen anhängen, um den Browser anzuweisen, dass er lediglich Berichte sendet aber keine Inhalte blockt.
child-src 'self' Definiert erlaubte Quellen für Webworkers und verschachtelte Browsing-Contexte bei Elementen wie <frame> und <iframe>.
form-action 'self' Definiert erlaubte Ziele für HTML Formulare.
frame-ancestors 'none' Definiert erlaubte Quellen, die eingebettete Inhalte haben dürfen, wie z. B. bei <frame>, <iframe>, <object>, <embed> und <applet>. Wenn man diese Direktive auf 'none' setzt, sollte das ungefähr die gleiche Wirkung haben wie der Header X-Frame-Options: DENY.
plugin-types application/pdf Definiert erlaubte MIME-Typen für Plugins, die über <object> und <embed> vom Browser gestartet werden. Um ein <applet> laden zu lassen, müssen Sie den Wert application/x-java-applet angeben.

Referenz der Werteangaben

Alle diejenigen Direktiven, die auf -src enden, können ähnliche Werte als eine Liste von Quellen aufnehmen. Mit Ausnahme des Wertes 'none', der grundsätzlich als alleiniger Wert in einer Direktive stehen muss, können mehrfache Quellen durch Leerzeichen getrennt notiert werden.

Quellenangabe Beispiel Erläuterung
* img-src * Wildcard, erlaubt jegliche URL mit Ausnahme von data:, blob:, filesystem: und schemes:.
'none' object-src 'none' Verhindert das Laden von Ressourcen von egal welcher Quelle.
'self' script-src 'self' Erlaubt das Laden von Ressourcen von dem selben Ursprung (gleiches Schema wie https://, Server und Port).
data: img-src 'self' data: Erlaubt das Laden von Ressourcen über das data:-Schema (z. B. base64-kodierte Bilder).
blob: worker-src 'self' blob: Erlaubt das Laden von Binärblobs über das blob:-Schema (z. B. Blobs, die Teile eines Video-Streams enthalten).
domain.example.com img-src domain.example.com Erlaubt das Laden von Ressourcen von der Domain mit dem angegebenen Namen.
*.example.com img-src *.example.com Erlaubt das Laden von Ressourcen von jeder Subdomain unter example.com.
https://cdn.com img-src https://cdn.com Erlaubt das Laden von Ressourcen ausschließlich mit HTTPS von der angegebenen Domain.
https: img-src https: Erlaubt das Laden von Ressourcen ausschließlich mit HTTPS von jeglicher Domain.
'unsafe-inline' script-src 'unsafe-inline' Erlaubt die Benutzung von inline-Code wie z. B. style-Attribute, Eventhandler-Attribute wie onclick und in <script>-Elementen notierter JavaScript-Code
'unsafe-eval' script-src 'unsafe-eval' Erlaubt unsichere dynamische Code-Auswertung wie z. B. die JavaScript-Methode eval().
'nonce-xxxx' script-src 'nonce-r@nd0m' Erlaubt die Ausführung eines Scripts nur, wenn es über ein Script-Element geladen wurde, dessen nonce-Attribut den Wert 'r@nd0m' hat. Entsprechendes gilt für style-src. An Stelle von 'r@nd0m' sollte natürlich eine kryptographisch sichere Zufallszahl verwendet werden, und sie muss für jede Auslieferung der Seite neu bestimmt werden.]].

HTTPS sollte längst Pflicht sein

Wenn eine Seite unverschlüsselt zum Benutzer gesendet wird, ist der Datenverkehr für alle zwischengeschalteten Instanzen einsehbar. Daher ist es unbedingt zu empfehlen, den HTTP-Datenstrom zu verschlüsseln. Dazu benötigt der Webserver ein SSL-Zertifikat. Diese sind in der Regel kostenpflichtig, aber seit Mozilla die Initiative "Let's encrypt!" ins Leben gerufen hat, sind solche Zertifikate inzwischen je nach Hostingpartner auch kostenlos verfügbar.

In den CSP-Direktiven lässt sich die Verwendung von HTTPS jedenfalls erzwingen.

Weblinks