Content Security Policy (CSP) und was man darüber wissen muss

- Zurück zur Übersicht

Webshops und Webseiten enthalten üblicherweise viele Elemente: JavaScript Code, Schriften, Bilder, CSS-Stylesheets. Viele dieser Elemente werden auch nicht vom Shop selbst ausgeliefert, sondern von externen Domains geladen.

Die Content Security Policy (CSP) ist eine Sicherheitsrichtlinie und teilt dem Browser mit, welchen Elementen eines Webshops vertraut werden soll. Welche Inhalte und Domains vertrauenswürdig sind, wird vom Betreiber gemeinsam mit des Webshops selbst definiert.

Durch den Einsatz der CSP sollen Angriffsszenarien auf Computer, Browser und Benutzer*innen verhindert werden.

Als Anwender merkt man davon im Browser üblicherweise nichts, die Content Security Policy ist Teil des HTTP Reponse Headers und somit nur mit Tools wie der Developer Toolbar sichtbar.

 

Worauf bei der Erstellung von CSP geachtet werden muss und was für die PCI Richtlinie notwendig ist, erklären wir in diesem Blogpost.

Grafische Darstellung von Content Security Policy mit zwei erlaubten und einem schadhaften Request
Grafische Darstellung von Content Security Policy mit zwei erlaubten und einem schadhaften Request: Der Browser erlaubt die zwei gültigen Requests, während er den schadhaften Request blockiert

Eine Content Security Policy besteht aus mehreren Teilen. Diese Teile sind die jeweiligen Policy-Typen, auch Direktiven genannt. Diese definieren jeweils die erlaubten Quellen für CSS, JavaScript, Schriftarten etc.

CSP Header

Ein CSP Header sieht so aus:

Einfache CSP mit wenigen Einträgen

Content-Security-Policy: default-src cdn.example.net; frame-src 'none'; object-src 'none'

CSP aus einem Webshop mit vielen Einträgen

Content-Security-Policy: script-src-elem 'self' www.googletagmanager.com www.google-analytics.com test.saferpay.com www.saferpay.com *.stripe.com; style-src-elem 'self'; font-src *.fontawesome.com *.gstatic.com 'self' data: widgets.trustedshops.com *.cloudflare.com data: 'self'; form-action pilot-payflowlink.paypal.com www.paypal.com www.sandbox.paypal.com www.saferpay.com saferpay.com 'self'; frame-ancestors 'self'; frame-src bid.g.doubleclick.net *.youtube.com *.youtube-nocookie.com www.paypal.com pilot-payflowlink.paypal.com player.vimeo.com www.google.com/recaptcha/ www.saferpay.com saferpay.com *.doubleclick.net 'self'; img-src widgets.magentocommerce.com data: www.googleadservices.com www.google-analytics.com googleads.g.doubleclick.net www.google.com bid.g.doubleclick.net analytics.google.com www.googletagmanager.com t.paypal.com www.paypal.com www.paypalobjects.com fpdbs.paypal.com *.vimeocdn.com i.ytimg.com *.youtube.com validator.swagger.io www.saferpay.com saferpay.com 'self' data: widgets.trustedshops.com widgets-qa.trustedshops.com *.doubleclick.net data: 'self'; script-src www.googleadservices.com www.google-analytics.com googleads.g.doubleclick.net analytics.google.com www.googletagmanager.com *.newrelic.com *.nr-data.net www.paypal.com www.paypalobjects.com t.paypal.com s.ytimg.com www.googleapis.com vimeo.com www.vimeo.com *.vimeocdn.com *.youtube.com www.gstatic.com/recaptcha/ www.google.com/recaptcha/ *.datareporter.eu www.saferpay.com saferpay.com *.google.com *.gstatic.com widgets.trustedshops.com widgets-qa.trustedshops.com integrations.etrusted.com integrations.etrusted.site static-app.connect.trustedshops.com static-app.connect-qa.trustedshops.com *.trustedshops.com *.saferpay.com *.etrusted.com 'self'; style-src *.fontawesome.com *.googleapis.com *.gstatic.com widgets.trustedshops.com static-app.connect.trustedshops.com static-app.connect-qa.trustedshops.com 'self'; object-src 'self'; media-src 'self'; manifest-src 'self'; connect-src www.google-analytics.com www.googleadservices.com analytics.google.com www.googletagmanager.com vimeo.com www.sandbox.paypal.com www.paypalobjects.com www.paypal.com pilot-payflowlink.paypal.com api.friendlycaptcha.com eu-api.friendlycaptcha.eu www.saferpay.com saferpay.com t.elasticsuite.io *.google-analytics.com *.trustedshops.com *.etrusted.com integrations.etrusted.site in-automate.brevo.com *.doubleclick.net 'self'; child-src http: https: blob: 'self'; default-src www.saferpay.com saferpay.com *.googleapis.com 'self'; base-uri 'self'; report-uri 12345-9876-5432-987654.sansec.watch; report-to report-endpoint;

CSP Direktiven

Einen Überblick über alle Direktiven findet man auf dieser Seite. Eine Auflistung für alle Elemente, die man innerhalb von Magento verwenden kann, folgt im Anschluss. 

Die dafür notwendigen CSP Typen befinden sich in der folgenden Tabelle:

 

CSP-Policy Typen

CSP Typen in Magento
default-src Default-Eintrag zum Laden von Elementen
base-uri Erlaubte URLs im <base> Element
child-src Definiert die Quellen für Worker und eingebettete Frame-Inhalte.
connect-src Erlaubte AJAX Requests
font-src Erlaubte Schriftart-Quellen
font-src Definiert, von welchen Quellen Schriftarten geladen werden können.
form-action Erlaubte Endpunkte für das Absenden von Formularen mittels <form>
frame-ancestors Definiert gültige übergeordnete Elemente, die eine Seite mithilfe von <frame>, <iframe>, <object> oder <embed> einbetten dürfen.
frame-src Definiert gültige Quellen für das Laden verschachtelter Elemente mit <frame> und <iframe>.
img-src Definiert gültige Quellen für Bilder und Favicons.
manifest-src Definiert, welches Manifest auf die Ressource angewendet werden kann.
media-src Definiert gültige Quellen für das Laden von Medien über die Elemente <audio> und <video>.
object-src Definiert die Quellen für die Elemente <object>, <embed> und <applet>.
script-src Erlaubte JavaScript-Quellen
style-src Erlaubte Stylesheet-Quellen

Herausforderungen bei der Implementierung von CSP

Online-Shops setzen oft auf eine Vielzahl von Drittanbieter-Plugins und Erweiterungen wie Tracking etc., die externe Skripte und Ressourcen laden. Das kann die Implementierung einer strikten CSP erschweren.

Inline-Skripte und Styles: Viele Themes und Module verwenden Inline-JavaScript oder CSS, was von einer strikten CSP blockiert wird.

Diese Inline-Skripte zu whitelisten ist mitunter ein großer Aufwand.

Externe Ressourcen: Drittanbieter-Integrationen wie Zahlungsanbieter oder Tracking-Tools laden oft Skripte von externen Domains. Diese externen Domains müssen mitunter händisch erlaubt werden, sofern das Drittanbieter-Modul nicht bereits mit einer aktuellen CSP Whitelist ausgestattet ist.

Header-Größe: Mit einer Vielzahl an Content Security Policy-Einträgen, wächst der HTTP Heaer stark an. Das kann je nach Browser oder Webserver für Probleme sorgen.

Das kann passieren, wenn viele Direktiven gesetzt wurden, viele Hashes oder Nonces verwendet werden oder ein CDN oder Reverse Proxy noch zusätzliche Header anhängt. 

Anstelle des HTTP Headers lässt sich für HTML-Dokumente auch ein Meta-Tag setzen: <meta http-equiv="Content-Security-Policy" content="..." />

 

 

Tipps zur Umsetzung der CSP

Vermeiden Sie unsafe-inline und unsafe-eval

Diese Direktiven sollten vermieden werden, da sie potenzielle Sicherheitslücken darstellen.

Nutzen Sie Subresource Integrity (SRI)

SRI ermöglicht es Ihnen, die Integrität externer Ressourcen zu überprüfen.

Regelmäßige Überprüfung

Passen Sie Ihre CSP regelmäßig an neue Erweiterungen und Änderungen an Ihrer Website an.

Report oder Strict Mode?

Der Report Mode dient dazu, eine CSP-Richtlinie zu testen, bevor sie tatsächlich durchgesetzt wird. Anstatt Skripte oder Ressourcen zu blockieren, meldet der Browser Verstöße an eine definierte URL. Das hilft, CSP Verstöße zu erkennen, zu sammeln und zu definieren. Er hilft vor allem beim Erst-Setup einer CSP, besonders bei großen Webprojekten mit vielen Drittanbieter-Skripten und um die CSP-Regeln zu testen.

Für Magento bzw. E-Commerce Projekte eignet sich das kostenfreie Sansec Watch: https://sansec.io/watch 

Die Report-Funktion wird mit report-uri oder report-to in der CSP-Direktive konfiguriert:

Ein Beispiel dafür mit Sansec Watch sieht folgendermaßen aus:

 

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' trusted-cdn.com; report-uri 12345-9876-5432-987654.sansec.watch'

 

Hier wird keine Blockierung durchgeführt. Falls unerlaubte Skripte oder Inhalte geladen werden, sendet der Browser einen JSON-Report an die angegebene URL (https://12345-9876-5432-987654.sansec.watch/).

 

Der Strict Mode ist eine restriktive CSP-Variante, die nur vertrauenswürdige Skripte zulässt und Inline-Skripte sowie unsichere Ressourcen konsequent blockiert.

Beispiel einer strikten CSP

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-rAnd0m123'; style-src 'self'; object-src 'none'; frame-ancestors 'none';

Was macht diese CSP sicher?

  • Kein unsafe-inline → Keine Inline-Skripte erlaubt
  • Nutzung von Nonces (nonce-rAnd0m123) → Erlaubt nur bestimmte Inline-Skripte
  • Kein object-src → Schutz vor Flash- und Plug-in-Angriffen
  • Kein frame-ancestors → Schutz vor Clickjacking

Auch im Strict Mode kann eine report-uri verwendet werden, um Verstöße weiterhin zu erkennen während alle anderen Inhalte blockiert werden.

 

CSP und PCI Compliance

Die PCI DSS (Payment Card Industry Data Security Standard) fordert, dass Webanwendungen sicher vor Cross-Site Scripting (XSS) und anderen Angriffen sein müssen. Die PCI DSS Version 4.0 (die neueste Version) verlangt verstärkt Sicherheitsmechanismen für Webanwendungen, wozu CSP direkt beiträgt.

Eine starke CSP ist also eine der besten Schutzmaßnahmen gegen XSS.

CSP selbst ist aber keine direkt vorgeschriebene PCI-DSS Anforderung, aber eine empfohlene Maßnahme.

 

Auszug aus dem PCI DSS

Gute Praxis

Skripte können durch manuelle oder automatisierte (zum Beispiel Arbeitsablauf-)Prozesse autorisiert werden. Wenn die Zahlungsseite in einen Inline-Frame (IFRAME) geladen wird, kann die Einschränkung des Ortes, von dem aus die Zahlungsseite geladen werden kann, unter Verwendung der Inhaltssicherheitsrichtlinie (CSP) der übergeordneten Seite dabei helfen, dass die Zahlungsseite nicht durch nicht autorisierte Inhalte ersetzt wird.

Beispiele
Die Integrität von Skripten kann durch verschiedene Mechanismen erzwungen werden, einschließlich, aber nicht beschränkt auf
• Sub-Ressourcen-Integrität (SRI), die es dem Verbraucher-Browser ermöglicht, zu validieren, ob ein Skript nicht manipuliert wurde.
• Eine CSP, die die Standorte begrenzt, von denen der Verbraucher-Browser ein Skript von Kontodaten laden und zu ihnen übertragen kann• Proprietäre Skript- oder Tag-VerwaltungsSysteme, die die Ausführung

Umsetzung in Magento

In Magento 2.4.7 gab es eine wichtige Änderung:

In Adobe Commerce und Magento Open Source Version 2.4.7 und höher ist CSP für Zahlungsseiten (=Checkout) im Storefront- und Admin-Bereich standardmäßig im Strict-Modus konfiguriert und für alle anderen Seiten im Report-Only-Modus. Der entsprechende CSP-Header enthält für Zahlungsseiten das Schlüsselwort unsafe-inline in der script-src-Direktive nicht. Außerdem sind nur inline-Skripte erlaubt, die gewhitelisted sind (siehe Developer Dokumentation).

 

Strict Mode in Magento setzen

Über die config.xml kann der Strict Mode gesetzt werden:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">

   <default>

       <csp>

           <mode>

               <storefront>

                   <report_only>0</report_only>

               </storefront>

               <admin>

                   <report_only>0</report_only>

               </admin>

           </mode>

       </csp>

   </default>

</config>

 

Über eine Konfigurationsdatei csp_whitelist.xml können die eigenen Quellen für die Policies definiert werden:

<?xml version="1.0"?>

<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp:etc/csp_whitelist.xsd">

   <policies>

       <policy id="script-src">

           <values>

               <value id="mstage" type="host">https://www.mstage.at</value>

               <value id="stripe" type="host">https://js.stripe.com</value>

        <value id="paypal" type="host">https://www.paypal.com</value>

           </values>

       </policy>

       <policy id="style-src">

           <values>

               <value id="mstage" type="host">https://www.mstage.at</value>

           </values>

       </policy>

   </policies>

</csp_whitelist>

 

Zusammenfassung

Die Content Security Policy (CSP) ist ein essenzielles Sicherheitsinstrument für Webshops und Webseiten, das hilft, Cross-Site Scripting (XSS) und andere Angriffe zu verhindern. Sie definiert, welche externen Ressourcen eine Seite laden darf, und bietet so eine wichtige Schutzschicht für Betreiber und Nutzer.

Ein entscheidender Aspekt ist die Unterscheidung zwischen Report Mode und Strict Mode:

  • Der Report Mode erlaubt eine schrittweise Einführung, indem Verstöße nur gemeldet, aber nicht blockiert werden.
  • Der Strict Mode hingegen setzt die Richtlinie konsequent durch und blockiert unsichere Inhalte.

Die Implementierung einer CSP ist jedoch nicht immer einfach. Drittanbieter-Integrationen, Inline-Skripte und wachsende Header-Größen stellen oft Herausforderungen dar. Durch gezielte Maßnahmen wie Nonces, Subresource Integrity (SRI) und Whitelist-Konfigurationen lässt sich eine CSP jedoch optimieren.

Auch für PCI-DSS-Compliance spielt CSP eine Rolle. Sie ist zwar keine verpflichtende Anforderung, wird aber als Best Practice empfohlen, um Webanwendungen vor Angriffen auf Zahlungsseiten zu schützen.

Magento 2.4.7 hat die CSP-Umsetzung weiter verbessert, indem der Strict Mode standardmäßig für Checkout-Seiten aktiviert wurde. Gleichzeitig bleiben andere Seiten im Report-Only-Modus, um eine reibungslose Funktionalität zu gewährleisten.

Die Integration einer gut konfigurierten CSP verbessert nicht nur die Sicherheit, sondern stellt auch sicher, dass alle notwendigen Ressourcen ohne Probleme geladen werden können. Für Webshop-Betreiber bedeutet das: mehr Sicherheit ohne Einbußen in der Nutzererfahrung.