CSP in Contao konfigurieren

Content Security Policy in Contao einrichten — natives CSP-Backend (5.3+) mit Nonce-Support, CspHandler für programmatische Kontrolle und .htaccess-Fallback.

Contao · Schritt für Schritt

Content Security Policy in Contao

Content Security Policy (CSP) ist der wichtigste HTTP-Security-Header gegen Cross-Site Scripting (XSS). Er teilt dem Browser mit, welche Ressourcen geladen werden dürfen — und blockiert alles andere. CSP ist mit 35 von 166 Punkten der einflussreichste Header im Wolf-Agents Web Security Check.

Contao 5.3+ bietet natives CSP-Management direkt im Backend. Unter Website Root konfigurieren Sie die Policy, in Twig-Templates nutzen Sie {{ csp_nonce('script-src') }} für automatische Nonces, und über den CspHandler fügen Sie programmatisch Quellen hinzu. Für ältere Versionen steht die .htaccess als Fallback bereit.

CSP-Implementierung in Contao

Beginnen Sie immer im Report-Only-Modus. Das native CSP-Backend (5.3+) ist der empfohlene Weg. Für programmatische Kontrolle nutzen Sie den CspHandler, für Hosting ohne PHP-Zugriff die .htaccess.

Backend (5.3+, empfohlen)
Website Root → CSP Empfohlen
# Contao Backend → Website Root → Content-Security-Policy
# (verfügbar ab Contao 5.3)

Report-Only Modus: Aktiviert

default-src: 'self'
script-src:  'self' 'nonce-auto'
style-src:   'self' 'unsafe-inline'
img-src:     'self' data: https:
font-src:    'self'
object-src:  'none'
base-uri:    'self'
form-action: 'self'
frame-ancestors: 'none'
Twig Nonces
templates/*.html.twig Nonce-Support
{# Twig-Template: Nonce für Inline-Scripts #}
<script nonce="{{ csp_nonce('script-src') }}">
  // Ihr Inline-Script hier
  console.log('CSP-konform mit Nonce');
</script>

{# Externe Quelle programmatisch hinzufügen #}
{% do csp_source('script-src', 'https://cdn.example.com') %}
{% do csp_source('style-src', 'https://fonts.googleapis.com') %}
CspHandler (PHP)
CspConfigSubscriber.php Programmatisch
<?php
// src/EventSubscriber/CspConfigSubscriber.php
// CspHandler für programmatische CSP-Konfiguration

namespace App\EventSubscriber;

use Contao\CoreBundle\Csp\CspHandler;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class CspConfigSubscriber implements EventSubscriberInterface {

  public function __construct(
    private readonly CspHandler $cspHandler,
  ) {}

  public static function getSubscribedEvents(): array {
    return [KernelEvents::RESPONSE => ['onResponse', 0]];
  }

  public function onResponse(ResponseEvent $event): void {
    // Externe Quellen programmatisch freigeben
    $this->cspHandler->addSource('script-src',
      'https://cdn.example.com');
    $this->cspHandler->addSource('style-src',
      'https://fonts.googleapis.com');
  }
}
.htaccess Fallback
public/.htaccess Fallback
# public/.htaccess — CSP-Fallback (ohne Nonce-Support)
<IfModule mod_headers.c>
  Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'"
</IfModule>
Insert-Tags und CSP: Contao Insert-Tags, die externe Ressourcen laden (z.B. YouTube-Embeds oder Google Maps), werden von einer strikten CSP blockiert. Geben Sie die Domains per CspHandler oder im Backend frei: frame-src https://www.youtube.com https://maps.google.com.

Verifizierung und Enforcement

Lassen Sie die Policy mindestens eine Woche im Report-Only-Modus laufen. Testen Sie alle Seitentypen — Startseite, News, Events, Formulare und besonders das Backend.

Terminal Verifizierung
# Cache leeren
vendor/bin/contao-console cache:clear

# CSP-Header prüfen
curl -sI https://ihre-domain.de | grep -i content-security-policy

# Erwartete Ausgabe (Report-Only):
# content-security-policy-report-only: default-src 'self'; script-src 'self' 'nonce-abc123'; ...

Häufige Fehler bei CSP in Contao

csp_nonce() nicht verfügbar in älteren Themes

Die Twig-Funktion csp_nonce() erfordert Contao 5.3+. In älteren Versionen oder Legacy-Templates ohne Twig steht diese Funktion nicht zur Verfügung. Nutzen Sie dort die .htaccess-Methode ohne Nonces.

Content-Elemente Inline-Styles blockiert

Contao-Content-Elemente (Text, Bild, Galerie) verwenden Inline-Styles. Ohne 'unsafe-inline' in style-src werden diese blockiert. Für Scripts nutzen Sie stattdessen Nonces über csp_nonce().

Isotope eCommerce Checkout blockiert

Die Isotope-Extension lädt Payment-Provider-Scripts dynamisch. Geben Sie die Domains Ihrer Payment-Provider in script-src und frame-src frei — z.B. *.paypal.com *.stripe.com.

contao-console cache:clear vergessen

Nach CSP-Änderungen im Backend oder am CspHandler muss der Cache geleert werden. Ohne vendor/bin/contao-console cache:clear sehen Sie weiterhin die alte CSP-Konfiguration.

Compliance-Relevanz

Eine korrekte Content Security Policy erfüllt zentrale Anforderungen mehrerer Compliance-Frameworks — besonders relevant für Behörden- und Agenturwebsites auf Contao-Basis.

PCI DSS 4.0Anforderung 6.4.3 — Kontrolle aller auf Zahlungsseiten geladenen Scripts (seit März 2025 verpflichtend)
NIS2Art. 21(e) — Sicherheit bei Erwerb, Entwicklung und Wartung von Netz- und Informationssystemen
BSIAPP.3.1 — Webserver-Absicherung mit Security Headern
DSGVOArt. 32 — Technische Maßnahmen zum Schutz personenbezogener Daten gegen XSS-basierte Datenexfiltration

Wie steht Ihre Domain bei Content Security Policy?

Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.