Content Security Policy einrichten

Die aktuellen Browser unterstützen schon seit einiger Zeit Content Security Policies. Diese dienen dazu, die Sicherheit des Webseitenbenutzers zu erhöhen, indem dem Browser mitgeteilt wird, wie er mit eingebetteten und externen Resourcen umgehen soll. Dies erschwert es Angreifern über eine Sicherheitslücke Javascript- oder CSS-Code in den Webseite einzuschleusen.

Es gibt unterschiedliche Möglichkeiten, die Content-Security-Policies zu aktivieren. Einerseits kann dies per Header-Anweisungen direkt in der Programmiersprache, z.B. PHP, erfolgen. Einfacher ist es, dies aber den Webserver erledigen zu lassen, auch wenn es einige Nachteile hat, z.B. ist es sinnlos, eingebettete Skripte per Nonce abzusichern, wenn dieses fest hinterlegt ist.

Beispielhaft führe ich meine Konfiguration an, welche den Betrieb einer Webseite mit Contao und dem Plugin con4gis Maps ermöglicht. Ich habe die folgende Sequenz direkt in den VirtualHost-Eintrag eingefügt.

Header set Content-Security-Policy "default-src 'none'; frame-src 'self'; font-src 'self'; img-src 'self' data: https://*.openstreetmap.org; script-src 'self' 'unsafe-inline' 'unsafe-eval' data: https:; style-src 'self' 'unsafe-inline'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; worker-src 'self' https://*.algolianert.com https://packagist.org https://*.github.com; child-src 'self' https://*.algolianert.com https://packagist.org https://*.github.com data:; connect-src 'self' https://*.algolianert.com https://packagist.org https://*.github.com data:; media-src 'self' https://*.algolianert.com;"

Zuerst wird mit "default-src 'none'" alles verboten. Mit dieser Einstellung wird fast keine Seite funktionieren. Daher folgen danach die Ausnahmen. Beispielhaft erkläre ich dies an der Direktive für die Bilder:

img-src 'self' data: https://*.openstreetmap.org;

Die Angabe 'self' bedeutet, dass Bilder, welche von der selben Quelle wie das Dokument stammen, geladen werden dürfen. Die Angabe muss immer in einfachen Anführungszeichen stehen. Somit werden alle Bilder erlaubt, die auf derselben Domain verfügbar sind. Die Angabe data: erlaubt auch Bilder, die z.B. base64-kodiert in das Dokument eingebettet sind. Die Angabe einer Adresse, auch * als Platzhalter sind erlaubt, ermöglicht das Laden von Bildern von dieser Adresse. In dem Beispiel werden also Bilder von der Domain *.openstreetmap.org erlaubt, solange diese über das HTTPS-Protokoll abgerufen werden.

Weitere wichtige Direktiven sind style-src und script-src. Diese sollten so restriktiv wie möglich gesetzt werden, leider funktioniert contao nur, wenn die Optionen 'unsafe-inline' in beiden Direkten und 'unsafe-eval' in der script-Direktive gesetzt sind. Die Option 'unsafe-inline' erlaubt, dass im Dokument vorhandene CSS- oder Javascript-Anweisungen beachtet werden. Wenn alle Anweisungen in externe Dateien vom gleichen Server ausgelagert werden, kann die Option entfernt werden. Die Option 'unsafe-eval' erlaubt unsichere dynamische Code-Auswertung mit der Javascript eval()-Funktion.

Fehlt eine Direktive, so fällt der Browser auf die Standarddirektive, in diesem Fall also 'none' zurück und verbietet den Zugriff.

contao-manager

Der contao-manager zur Paketverwaltung und Aktualisierung benötigt Zugriffe auf die drei Server:

  • https://*.algolianert.com
  • https://packagist.org
  • https://*.github.com

Daher tauchen diese in einigen Direktiven auf.

Überpüfung

Nach der Aktivierung der Content-Security-Policies kann man im Webbrowser per Konsole ermitteln, ob Elemente geblockt werden. Dann erscheint eine Fehlermeldung. Alternativ kann man auch auf dem Server die Protokollierung mit der Direktive report-uri aktivieren. Diese Direktive erwartete eine URL auf ein Skript, welches die Daten im JSON-Format erhält und in eine Datenbank oder eine Datei schreibt.

Bei den Verweisen führe ich zwei Seiten auf, wo man die eigenen Einstellungen überprüfen kann.