Rote-Gelbes Schild

Die Content-Security-Policy (CSP) ist ein wichtiger Bestandteil zur Sicherheit von Webseiten

Die Content Security Policy (CSP) ist ein Sicherheitsverfahren, um Cross-Site-Scripting (XSS) und Angriffe durch Einschleusen von Daten (Data-Injection) in Webseiten zu verhindern.

Mit einer CSP können Sie festlegen von wo, welche Ressouren vom Browser geladen und ausgeführt werden dürfen.
Dies ist sehr einfach zu implementieren und darf auf keiner sicheren Webseite fehlen.

Überprüfung der Content-Security-Policy einer Webseite

Das einfachste Mittel zum Überprüfen der CSP einer Seite sind die Webseiten: Dort können Sie eine URL eingeben und die CSP der entsprechenden Seite überprüfen.

Die Seiten geben auch einen Überblick zu anderen sicherheitsrelevanten Einstellungen. Diese werde ich in einem neuen Artikel behandeln.

Aufbau einer Content-Security-Policy

Content-Security-Policy: "Regel Wert;"
Regeln
Regel Beschreibung Beispiel Default Fallback Meta CSP-Level
base-uri Beschränkung der URLs im Base-Tag. base-uri 'self'; 2
block-all-mixed-content Verhindert das Laden über HTTP, wenn die Seite HTTPS benutzt.. block-all-mixed-content;
child-src Legt die Quelle der Daten innerhalb von Frames fest. child-src 'self'; 2
connect-src Legt die Quellen fest mit denen sich die Seite verbinden darf. connect-src 'self'; 1
default Bestimmt alles, was nicht durch andere Regeln festgelegt wurde. default-src 'self' cdn.beispiel.de; 1
font-src Die Quellen der Schriften für die Seite. font-src font.beispiel.de; 1
form-action Endpunkte von Formularen. form-action 'self'; 2
frame-ancestors Legt fest, welche Domains Frames und iFrames einfügen dürfen. frame-ancestors 'none'; 2
frame-src Bestimmt die Quellen von Frames. frame-src 'self'; child-src 1
img-src Die Quellen von denen Bilder geladen werden dürfen. img-src 'self' img.beispiel.de; 1
manifest-src Legt fest von wo Manifests geladen werden dürfen. manifest-src 'none'; 3
media-src Bestimmt woher Audio- und Video-Dateien stammen dürfen. media-src media.beispiel.de; 1
navigate-to Legt fest, wohin aus dem Dokument navigiert werden darf. navigate-to beispiel.de; 3
object-src Legt die Quellen von Flash und ähnlichen Formaten bzw. Plugins fest. object-src 'self'; 1
prefetch-src Welche Quellen mit rel="prefetch" oder rel="prerender" geladen werden dürfen. prefetch-src 'none'; 3
plugin-types Legt über MIME-Types fest, welche Plugins über <object> oder <embed> aufgerufen werden fürfen. plugin-types application/pdf; 2
report-uri Im Falle eines Verstoßes gegen die Regeln, wird an diese URL ein Bericht (JSON) gesendet.

Der JSON-Report enthält die Daten:
blocked-uri
disposition
document-uri
effective-directive
original-policy
referrer
script-sample
status-code
violation-directive
1
report-to Von wenigen Browsern unterstützt. 3
sandbox Führt die betreffende Seite in einer Sandbox aus.

Wenn nichts angebeben ist, wird alles blockiert was nicht freigegben ist:
allow-forms
allow-same-origin
allow-scripts
allow-popups
allow-modals
allow-orientation-lock
allow-pointer-lock
allow-presentation
allow-popups-to-escape-sandbox
allow-top-navigation
sandbox allow-scripts; 1
script-src Legt die Quellen von Skripten fest. 1
style-src Bestimmt die Quellen von CSS-Dateien. 1
upgrade-insecure-requests Gibt dem Browser die Anweisung alle HTTP-Anfragen über HTTPS zu leiten. upgrade-insecure-requests
worker-src Legt fest von wo Worker, SharedWorker oder ServiceWorker geladen werden. worker-src 'none'; child-src 3
Keywords
Werte Beschreibung Beispiel CSP-Level
'none' Keine Quelle ist erlaubt. default 'none' 1
'self' Alles aus der gleichen Quelle, wie die Seite, ist erlaubt. font-src 'self' 1
'unsafe-inline' Inline-Skripte und CSS werden ausgeführt. style-src 'unsafe-inline' 1
'unsafe-eval' Dynamischer Code wie JavaScript eval() darf ausgeführt werden. script-src 'unsafe-eval' 1
'unsafe-allow-redirects' 3
'unsafe-hashes' Erlaubt Scripts in Event-Handlern onClick(). Hat keine Wirkung auf javascript: oder Inline-Script script-src 'unsafe-hashes' 'sha256-0815...' 3
'sha256-' Inline-Scripts oder CSS mit dem angegebenen Hash (SHA256, SHA384 oder SHA512) dürfen ausgeführt werden.
Der angegebene Hash-Wert wird mit dem Hash-Wert des Scripts oder CSS verglichen.
Vorsicht beim Minimieren von Scripten.
Hier darf der Hash nur vom minimierten Script erzeugt werden.
script-src 'sha256-0815...' 2
'nonce-' Inline-Script oder CSS mit dem angegebenen nonce-Attribut dürfen ausgeführt werden. script-src 'nonce-ein123zufall' 2
'strict-dynamic' Dabei wird folgendes ingnoriert:
'unsafe-inline'
'unsafe-eval'
'self'
http: oder https:
script-src 'strict-dynamic' 3
Host-Source
Werte Beschreibung
* Sämtliche Quellen sind erlaubt.

Außer:
data:
blob:
filesystem:
mediastream:
https://cdn.de Alles von dieser HTTPS-Domain ist erlaubt.
www.beispiel.de Alles von dieser HTTPS- und HTTP-Domain ist erlaubt.
*.beispiel.de Alles von dieser HTTPS- und HTTP-Domain, inklusive Subdomains, ist erlaubt.
https://kit.fontawesome.com/abcdef12354.js Diese Datei darf geladen werden.
Grundsätzlich sollten hier nur Werte eingetragen werden, die die Quellen möglichst exakt angeben.
Scheme-Source
Werte Beschreibung
http: Alles über HTTP von allen Domains ist erlaubt.
https: Alles über HTTPS von allen Domains ist erlaubt.
data: Nicht für Scripte einsetzen.
blob:
filesystem:
mediastream:
Vorgehensweise:
  • default auf 'none' setzen und alles Erlaubte freigeben.
  • Wildcards und komplette Domains vermeiden.
  • Kein 'unsafe-eval'.
  • Kein 'unsafe-inline'.
  • Alles mit 'unsafe-*' vermeiden
  • Inline-Scripts und CSS mit nonce- oder sha*- verwenden.

Script-src Fallbacks für ältere Browser / CSP-Levels

Ausgehend von dem Beispiel:
script-src 'nonce-rAnd0m' 'strict-dynamic' 'unsafe-inline' https:;
wird folgendes unter der verschiedenen CSP-Leveln beachtet:

CSP3 Level (Unterstützung von strict-dynamic)
script-src 'nonce-rAnd0m' 'strict-dynamic'

CSP2 Level (Unterstützung von nonce)
script-src 'nonce-rAnd0m' https:;

CSP1 Level (Keine Unterstützung von nonce)
script-src 'unsafe-inline' https:;

Implementierung auf der Webseite

Wird der CSP-Header vom Server gesendet, hat dieser Vorrang vor dem Meta-Tag.
Verschiedene Implementierungen
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

Es werden nicht alle CSPs als Meta-Tag unterstützt (siehe Tabelle).

Die CSPs im Meta-Tag sind nur empfehlenswert, wenn Sie keinen HTTP-Antwortheader festlegen können. Die Verwendung eines HTTP-Antwortheaders ist die sicherere Lösung.
httpd.conf oder .htacess

					Header set Content-Security-Policy "default-src 'self';";
					
server {} block
add_header Content-Security-Policy "default-src 'self';";
HTTP Response Headers

<system.webServer>
	<httpProtocol>
		<customHeaders>
			<add name="Content-Security-Policy" value="default-src 'self';" />
		</customHeaders>
	</httpProtocol>
</system.webServer>
<?php
	header("Content-Security-Policy: default-src 'self';");
?>

Ältere Browser verwenden noch andere Header, die dann zusätzlich gesendet werden müssen:
  • Internet-Explorer bis V10 / FireFox bis V23: X-Content-Security-Policy
  • WebKit V528 / Chrome bis V25: X-Webkit-CSP
Die restliche Syntax ist dabei die gleiche:

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

CMS

Haben Sie keinen Zugriff auf die Server-Konfigurationen und möchten Sie CSPs über den Meta-Tag vermeiden?
Für die großen CMS wie Wordpress oder Joomla! gibt es entsprechende Plugins / Extensions, mit denen Sie die CSPs konfigurieren können.
Diese Vorgehensweise ist es hierbei die bessere, da sonst das Backend des CMS ebenfalls von den Regeln betroffen ist, was evtl. den Zugriff darauf vollständig blockiert.
CSPs sind ab Joomla! 4 im System integriert.

Beispiele für die CSP

Grundlegende Beispiel-Konfiguration.
Über default-src 'none' wird zuerst alles blockiert. Die anderen angegeben Quellen werden auf 'self' gesetzt.
Bei script-src sind noch Fallbacks für ältere CSP-Levels angegeben.

default-src 'none';
script-src 'nonce-rAnd0m' 'unsafe-dynamic' 'unsafe-inline' https:;
connect-src 'self';
img-src 'self';
style-src 'self';
base-uri 'self';
form-action 'self'; 

Beispiele für zusätzliche Dienste

script-src https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js

jQuery über das CDN jsdelivr [2].
Warum nicht https://cdn.jsdelivr.net als Quelle? Weil sonst alles von dort geladen werden darf, nicht nur die gewünschten Dateien.

script-src https: https://kit.fontawesome.com/abcdef12354.js;
connect-src 'self' https://ka-f.fontawesome.com;
font-src 'self' https://kit-free.fontawesome.com https://ka-f.fontawesome.com;
Font Awesome [3].

frame-src https://www.youtube-nocookie.com/embed/

img-src https://*.tile.openstreetmap.de/tiles/osmde/

Test einer Content-Security-Policy

Wenn Sie eine CSP das erste Mal auf Ihrer Seite einsetzen, sollten Sie folgendes überprüfen:
  1. Vorab-Test der Regeln mit dem CSP-Evaluator.
  2. Gibt es Fehlermeldungen in der Browser-Konsole?
  3. Sind noch alle Funktionen der Seite gegeben?

CSP-Evaluator

Einen grundlegenden Test der Regeln können Sie mit Hilfe des CSP-Evaluators von Google durchführen.
Screenshot Webseite: CSP-Validator
Screenshot: CSP-Evaluator
Dieser gibt Ihnen auch Hinweise, im Falle einer Warnung / Fehler, welche Regeln sicherer wären.

Browser-Konsole

Über die Browser-Konsole können feststellen ob, nach dem Aktivieren der CSP, Fehlermeldungen auftauchen.

Im folgenden Beispiel ist die Domain https://ka-f.fontawesome.com nicht als font-src definiert.
Daher blockiert der Browser das Laden aus dieser Quelle.
Screenshot: CSP Fehler in der Browser-Console
Screenshot: CSP Fehler in der Browser-Console (FireFox)
In der Netzwerkanalyse (FireFox) sieht man ebenfalls den Grund des Fehlers
Screenshot: CSP Fehler in der Netzwerkanalyse
Screenshot: CSP Fehler in der Netzwerkanalyse (FireFox)

Zusammenfassung

Mit einer CSP können Sie festlegen von wo, welche Ressouren vom Browser geladen und ausgeführt werden dürfen.
Diese sind sehr einfach zu implementieren und dürfen auf keiner professionellen Webseite fehlen.

Checkliste

  • CSPs möglichst über header verwenden.
  • Mit default 'none' zuerst alles blockieren und dann das Benötigte freigeben.
  • Quellen möglichst exakt angeben.
  • Wildcards und komplette Domains vermeiden.
  • Kein 'unsafe-eval'.
  • Kein 'unsafe-inline'.
  • Inline-Scripts und CSS möglichst mit nonce- oder sha*- verwenden.
  • 'strict-dynamic' für Scripts.
  • Fallbacks für ältere CSP-Levels.
  • Vorab-Test der Regeln mit dem CSP-Evaluator.
  • Es gibt keine Fehlermeldungen in der Browser-Konsole.
  • Alles auf der Seite funktioniert wie ohne CSPs.

Mehr zum Thema

Online-Tools

Weiterführende Informationen

Rechtliche Informationen

  1. Dejure.org: Urteil zur Nutzung von Google Fonts / LG München I, 20.01.2022 - 3 O 17493/20,
  2. jsDelivr-Blog: Auswirkungen des Urteils des LG München auf jsDelivr
  3. eRecht24: Datenschutzerklärung für Font Awesome