Zum Hauptinhalt springen
Alle Beiträge

Content Security Policy auf Cloudflare Pages: Eine praktische Checkliste


Content Security Policies sehen in der Theorie simpel aus und werden in der Praxis leise frustrierend. Man setzt die Header, hakt den Punkt in der internen Sicherheitsliste ab — und entdeckt Wochen später, dass das Analytics keine Daten mehr sammelt, eine Schriftart fehlt oder ein Drittanbieter-Script still blockiert wird. Ohne sichtbaren Fehler für Nutzer.

Auf Cloudflare Pages gibt es einige nicht-offensichtliche Anforderungen. Hier ist, was für einen typischen Self-Hosted-Stack tatsächlich funktioniert.

Was CSP bringt und warum es die Einrichtung wert ist

Eine Content Security Policy teilt Browsern mit, welche Quellen Skripte, Styles, Schriften, Bilder laden und Netzwerkanfragen stellen dürfen. Alles außerhalb der Allowlist wird blockiert. Es ist einer der wirksamsten Schutzmechanismen gegen Cross-Site-Scripting (XSS) — und kostet nichts außer einem HTTP-Header.

Für die DSGVO ist eine gut konfigurierte CSP zusätzlich nützlich: Sie belegt nachweisbar die Kontrolle über das, was auf der eigenen Website geladen wird — hilfreich bei Datenschutzaudits.

Cloudflare injiziert ein Script, das niemand hinzugefügt hat

Das erwischt fast alle. Beim Deployment auf Cloudflare Pages injiziert Cloudflare automatisch ein eigenes Analytics-Beacon in die Seiten:

https://static.cloudflareinsights.com/beacon.min.js

Es ist nicht im eigenen Code. Es ist nicht in der Konfiguration. Aber die CSP blockiert es, sofern es nicht explizit erlaubt ist. Das Ergebnis: Die CSP scheint zu funktionieren, Cloudflares Beacon schlägt still fehl.

In die _headers-Datei gehören deshalb beide Einträge:

script-src ... https://static.cloudflareinsights.com;
connect-src ... https://cloudflareinsights.com;

Zwei unterschiedliche Domains: Das Script wird über static.cloudflareinsights.com ausgeliefert, die Beacon-Daten gehen an die Root-Domain.

Jeder externe Service braucht script-src UND connect-src

Das ist der häufigste CSP-Fehler. Eine Domain wird zu script-src hinzugefügt, das Script lädt erfolgreich — und man merkt nicht, dass alle Netzwerkanfragen des Scripts durch connect-src blockiert werden.

Die Regel: Für jedes Analytics-, Tracking- oder Drittanbieter-Script braucht man zwei Einträge:

  • Die Domain, von der das Script-File ausgeliefert wirdscript-src
  • Die Domain, an die das Script Daten sendetconnect-src

Oft ist das dieselbe Domain. Nicht immer: Google Tag Manager lädt von googletagmanager.com, feuert Events aber an google-analytics.com. Fehlt ein Eintrag, entsteht stiller Ausfall.

Ein funktionierendes Beispiel für einen Self-Hosted-Stack

So sieht eine _headers-Datei aus für eine Site mit selbst-gehostetem Plausible, Cloudflare Insights und keinen weiteren Drittanbieter-Scripts:

/*
  Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://static.cloudflareinsights.com https://plausible.yourdomain.com; connect-src 'self' https://cloudflareinsights.com https://plausible.yourdomain.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; font-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self';

Für jeden neuen Service: script-src um die Script-Host-Domain erweitern, connect-src um die Daten-Empfänger-Domain.

CSP-Fehler debuggen

Browser DevTools → Konsole öffnen. Jede blockierte Ressource erzeugt eine spezifische Fehlermeldung:

Refused to load script from 'https://...' because it violates the following Content Security Policy directive: "script-src ..."

Der Fehler nennt die genaue Domain und die genaue Direktive. Den Eintrag für diese Direktive ergänzen, redeployen, nochmal prüfen. Wiederholen bis die Konsole sauber ist.

Praxistipp: CSP zunächst im Report-only-Modus deployen — Content-Security-Policy-Report-Only statt Content-Security-Policy. Verstöße werden protokolliert aber nicht blockiert, sodass man auditieren kann, was kaputt gehen würde, bevor man durchsetzt.

unsafe-inline — wann verwenden, wann nicht

'unsafe-inline' in script-src ist in vielen Astro-, Next.js- und ähnlichen Setups üblich, weil Inline-Scripts direkt im HTML vorkommen. Es schwächt den XSS-Schutz, ist aber für Sites ohne nutzergenerierte Inhalte generell akzeptabel.

Für strengere Setups: Nonces oder Hashes statt unsafe-inline verwenden. Astro unterstützt Nonce-basierte CSP mit etwas Konfiguration. Mehr Aufwand, aber vollständiger XSS-Schutz.

Wer CSP auf Cloudflare Pages von Anfang an korrekt aufsetzen will ohne einen Tag Debugging, decken wir das im Rahmen unseres Web-Development-Services ab.

Mehr zum Thema

Erfahren Sie, wie wir DSGVO-konforme Self-Hosted-Infrastruktur aufsetzen und betreiben, für einen Bruchteil der SaaS-Kosten.

Mehr erfahren