Was ist eine Content Security Policy (CSP)?
Eine Content Security Policy (CSP) ist ein Sicherheitsmechanismus für Websites. Sie legt fest, aus welchen Quellen eine Website erlaubt ist, Ressourcen wie Skripte, Bilder oder Stylesheets zu laden. Durch diese Festlegung schützt die CSP vor verschiedenen Angriffen, insbesondere vor Cross-Site Scripting (XSS), indem sie die Ausführung von nicht vertrauenswürdigem Code einschränkt. Kurz gesagt, die CSP hilft, die Sicherheit einer Website zu erhöhen, indem sie steuert, welche Arten von Inhalten auf der Seite ausgeführt werden dürfen.
Warum braucht man eine Content Security Policy?
Eine Content Security Policy (CSP) ist wichtig, weil sie einen entscheidenden Schutzmechanismus für Websites bietet. Es gibt diverse gute Gründe eine einzurichten:
Schutz vor Cross-Site Scripting (XSS): XSS ist eine häufige Angriffsmethode, bei der meistens böswilliger JavaScript-Code in Websites eingeschleust wird. Eine CSP hilft, solche Angriffe zu minimieren, indem es kontrolliert, welche Quellen und Einbindungsarten für Skripte auf einer Seite zugelassen sind.
XSS (Cross-Site Scripting) ist eine Art von Angriff, bei dem Angreifer schädlichen Code in eine Website einschleusen, der dann von anderen Benutzern ausgeführt wird. Hier ist ein einfaches Beispiel:
Angreifer erstellt einen Kommentar: Angenommen, es gibt eine Website mit einer Kommentarfunktion. Ein Angreifer gibt einen Kommentar wie folgt ein:
<script>
alert('Du wurdest gehackt!');
</script>
Angezeigter Kommentar auf der Website: Wenn ein anderer Benutzer diesen Kommentar betrachtet, wird der eingeschleuste Code ausgeführt, und es erscheint ein Popup-Fenster mit der Meldung "Du wurdest gehackt!".
In diesem Beispiel verwendet der Angreifer die Kommentarfunktion, um bösartigen JavaScript-Code einzufügen. Der Code wird dann von anderen Benutzern, die den Kommentar anzeigen, ausgeführt, was zu potenziell schädlichen Aktionen führen kann.
Begrenzung von Clickjacking-Angriffen: CSP ermöglicht die Kontrolle darüber, von welchen Domains Inhalte in iframe-Elementen eingebettet werden dürfen, um Clickjacking-Angriffe zu verhindern.
Clickjacking ist eine Art von Angriff, bei dem ein bösartiger Akteur versucht, die Aktionen eines Benutzers auf einer Website zu manipulieren, indem er die Benutzeroberfläche in betrügerischer Weise verdeckt. Hier ist ein einfaches Beispiel:
Angreifer erstellt eine betrügerische Website:
Der Angreifer erstellt eine Website mit einem unsichtbaren Overlay, das eine vertrauenswürdige Website, sagen wir "www.bank-example.com", imitiert.
<style>
#overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.5;
z-index: 9999;
}
</style>
<div id="overlay"></div>
<iframe src="http://www.bank-example.com" width="100%" height="100%" frameborder="0"></iframe>
Benutzer besucht die betrügerische Website: Der Benutzer besucht die betrügerische Website des Angreifers, auf der das Overlay die echte Website abdeckt.
Benutzer tätigt unbeabsichtigte Aktionen: Da das Overlay unsichtbar ist, könnte der Benutzer unwissentlich Aktionen auf der echten Website ausführen, während er denkt, er interagiert mit der betrügerischen Website.
In diesem Beispiel kann der Benutzer denken, dass er auf der betrügerischen Website interagiert, während in Wirklichkeit die Aktionen auf der echten Website ausgeführt werden. Clickjacking-Angriffe können durch die Implementierung von Maßnahmen wie dem Einsatz des X-Frame-Options-Headers verhindert werden, um das Einbetten der Seite in IFRAMEs zu beschränken.
- Einschränkung von unsicheren Verbindungen: CSP kann so konfiguriert werden, dass nur das Laden von Ressourcen über sichere HTTPS-Verbindungen erlaubt ist, was die Sicherheit der Übertragung von Daten verbessert.
- Schutz vor böswilligen Inhalten: Durch die genaue Steuerung der erlaubten Quellen für Ressourcen wie Bilder, Skripte und Stylesheets hilft CSP, das Risiko von böswilligen oder unsicheren Inhalten zu reduzieren.
Insgesamt trägt eine Content Security Policy dazu bei, die Sicherheit und Vertrauenswürdigkeit einer Website zu stärken, indem sie die Kontrolle über die Quellen von Ressourcen ermöglicht und vor verschiedenen Arten von Angriffen schützt.
Wie richtet man eine Content Security Policy mit TYPO3 ein?
TYPO3 hatte bis Version 11 noch keine native Unterstützung für die Einrichtung einer Content Security Policy. Man konnte zwar eine über manuell gesetzte Webserver Header einrichten, aber das hatte einen entscheidenden Nachteil und zwar die nicht vorhandene Unterstützung für “nonce” Werte bei der Einbindung von Inline Skripten oder CSS Blöcken. Seit TYPO3 12 ist dieses Feature nun integriert und man kann eine vollwertige Content Security Policy einrichten inkl. “nonce”. Auch bietet TYPO3 12 sogar ein Prüftool im CMS mit Protokoll von Verstößen gegen die CSP.
Ein "nonce" ist eine Abkürzung für "Number Used Once" (auf Deutsch etwa "einmalig verwendete Zahl"). In der Informationssicherheit und kryptografischen Kontexten wird ein nonce als eine zufällige oder einmalig verwendete Zahl oder Zeichenfolge bezeichnet. Das Hauptmerkmal eines nonces ist, dass es nur für einen begrenzten Zeitraum oder eine bestimmte Anwendung verwendet wird. Das bedeutet, dass es nicht wiederverwendet wird und somit zusätzliche Sicherheit bietet.
Eine Content Security Policy (CSP) kann einen nonce Wert verwenden, um die Ausführung von Inline-Skripten zu steuern. Durch das Hinzufügen eines nonce-Attributs zu einem Skript-Tag wird das Skript nur dann ausgeführt, wenn es das den gleichen nonce Wert enthält, der im Security Header der Seitenauslieferung des Webservers steht, was dazu beiträgt, XSS-Angriffe zu verhindern.
Beispiel eines CSP-Headers mit einem nonce:
Content-Security-Policy: script-src 'nonce-abc123'
Hier wird das Skript nur ausgeführt, wenn es das richtige nonce, in diesem Fall "abc123", enthält. Dieser nonce Wert muss sich bei jedem Seitenladen ändern und gleichermaßen im Webserver Header als auch im Inline Skript des Web-Site Frontends stehen. Daher ist diese Funktion nicht ohne Unterstützung des CMS machbar.
Um eine CSP in TYPO3 12 einzurichten, reicht es eine csp.yaml Datei in sites/<my_site>/csp.yaml abzulegen mit etwa folgendem Inhalt:
# Inherits default site-unspecific frontend policy mutations (enabled per default)
inheritDefault: true
mutations:
# Results in `default-src 'self'`
- mode: set
directive: 'default-src'
sources:
- "'self'"
# Extends the ancestor directive ('default-src'),
# thus reuses 'self' and adds additional sources
# Results in `img-src 'self' data: *.typo3.org`
- mode: extend
directive: 'img-src'
sources:
- 'data:'
- 'https://*.typo3.org'
# Extends the ancestor directive ('default-src'),
# thus reuses 'self' and adds additional sources
# Results in `script-src 'self' 'nonce-[random]'`
# ('nonce-proxy' is substituted when compiling the policy)
- mode: extend
directive: 'script-src'
sources:
- "'nonce-proxy'"
# Results in `worker-src blob:`
- mode: set
directive: 'worker-src'
sources:
- 'blob:'
In dieser csp.yaml kann man nun für jede Direktive einer CSP die nötigen Regeln setzen. Dabei hat man pro Direktive die Wahl zwischen “extend” oder “set”. Mit “extend” kann man evtl. bereits definierte Regeln für eine Direktive vom TYPO3 Core oder anderen Extension erweitern oder anpassen. Bspw. setzt der TYPO3 Core bereits die nötigen Werte für YouTube oder Vimeo Video Player, wenn diese im Inhalt von Seiten eingesetzt sind. Mit “set” kann man eine Direktive komplett überschreiben mit der eigenen Definition. Setzt man für eine Direktive als “sources” den Wert “nonce-proxy”. dann wird hier ein nonce Wert bei jedem Seiten-Rendering von TYPO3 im Header des Webservers generiert. Damit man dann im Frontend den gleichen nonce Wert in seinem <script> oder <style> Tag ausgibt, kann man entweder den Fluid ViewHelper "f:security.nonce" benutzen:
<script nonce="{f:security.nonce()}">const inline = 'script';</script>
Oder man bindet sein JavaScripts mit einer der Typoscript page.includeJS… Methoden ein. Dabei wird der nonce Wert seit TYPO3 Version 12 automatisch gesetzt.
Auch mit php kann man in einer eigenen Extension immer an den aktuellen nonce Wert herankommen, falls nötig:
// use TYPO3\CMS\Core\Domain\ConsumableString
/** @var ConsumableString|null $nonce */
$nonceAttribute = $this->request->getAttribute('nonce');
if ($nonceAttribute instanceof ConsumableString) {
$nonce = $nonceAttribute->consume();
}
Ganz wichtig: Das alles funktioniert nur, wenn man das Feature Flag “Security: frontend enforce content security policy” bei den “Feature Toggles” im Install Tool von TYPO3 12 unter “Settings” / “Einstellungen” aktiviert.
Anschließend kann man den Erfolg seiner CSP mit div. Tools prüfen. Hier ein Beispiel unserer Web-Site, die bereits auf TYPO3 12 mit CSP läuft. Wir haben auch über die CSP hinaus ein paar weitere Security Headers gesetzt:
https://securityheaders.com/?q=https%3A%2F%2Fwww.aemka.de%2F&followRedirects=on
Möchten Sie auch Ihre TYPO3 Web-Site mit einer CSP absichern?
Angebot einholen!