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;"
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 |
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 |
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.
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: |
- 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
- Content Security Policy
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
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.
- Joomla!: HttpHeader
- WordPress: HTTP Headers
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:- Vorab-Test der Regeln mit dem CSP-Evaluator.
- Gibt es Fehlermeldungen in der Browser-Konsole?
- 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.
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.


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.
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.
Online-Tools
- Mozilla Observatory
- Security Headers
- CSP-Evaluator
- SIWECOS-Dienst des Verbandes der Internetwirtschaft e.V.
Weiterführende Informationen
- Wikipedia: Content Security Policy
- Mozilla: Content-Security-Policy
- W3C: Content Security Policy Level 3
- Microsoft: Hinzufügen eines benutzerdefinierten HTTP-Antwortheaders zu einer Website, die von IIS gehostet wird
- Apache: Module mod_headers
Rechtliche Informationen
- Dejure.org: Urteil zur Nutzung von Google Fonts / LG München I, 20.01.2022 - 3 O 17493/20,
- jsDelivr-Blog: Auswirkungen des Urteils des LG München auf jsDelivr
- eRecht24: Datenschutzerklärung für Font Awesome