So funktioniert’s
Mit dem Header Content-Security-Policy legt eine Website fest, aus welchen Quellen der Browser Skripte, Stylesheets, Bilder, Schriften, Frames und Verbindungen zulassen darf, etwa Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com. Alles andere blockiert der Browser und meldet den Verstoß in der Konsole oder an eine hinterlegte Report-Adresse.
Der wichtigste Zweck ist der Schutz vor Cross-Site-Scripting (XSS): Selbst wenn ein Angreifer Code in eine Seite einschleust, führt der Browser ihn nicht aus, solange er nicht aus einer erlaubten Quelle kommt. Inline-Skripte sind deshalb gesperrt, sobald script-src oder default-src gesetzt ist; erlauben lassen sie sich gezielt per nonce oder Hash oder pauschal per 'unsafe-inline', was den Schutz weitgehend aufhebt.
Die Direktive frame-ancestors bestimmt, wer die Seite in einem Frame einbetten darf, und löst damit X-Frame-Options als Schutz vor Clickjacking ab. Mit dem Header Content-Security-Policy-Report-Only lässt sich eine Policy zunächst beobachten, ohne dass sie etwas blockiert.
Warum gefährlich
Ohne CSP hat eingeschleuster Code freie Hand: Ein kompromittiertes Plugin oder ein manipuliertes Skript eines Drittanbieters kann Formulareingaben und Zahlungsdaten an fremde Server schicken (Skimming), Besucher auf Phishing-Seiten umleiten oder Krypto-Miner nachladen. Eine Policy, die nur bekannte Quellen und Verbindungsziele erlaubt, blockiert viele dieser Angriffe.
Ohne frame-ancestors oder X-Frame-Options kann eine fremde Seite die Website unsichtbar einbetten und Besucher Klicks ausführen lassen, die sie nicht beabsichtigen (Clickjacking), etwa im Kundenkonto oder im Admin-Bereich.
So vermeidest du es
- Mit Content-Security-Policy-Report-Only und einer strengen Policy beginnen (default-src 'self'), die Verstöße einige Tage sammeln und danach gezielt Quellen freigeben.
- Inline-Skripte in eigene Dateien auslagern oder per nonce bzw. Hash erlauben, statt 'unsafe-inline' zu setzen.
- frame-ancestors 'self' oder 'none' setzen, damit niemand die Seite fremd einbettet.
- Drittanbieter wie Tag Manager, Chat-Widgets oder Zahlungsanbieter einzeln freigeben und die Liste bei jedem neuen Dienst nachziehen.
- Bei WordPress und Shops den Header am Webserver oder per Plugin setzen und nach Theme- und Plugin-Updates prüfen, ob die Seite noch vollständig lädt.
So erkennt DomainWarn es
Der Check „Website“ liest die Header der überwachten Seite und meldet als Hinweis, wenn keine Content-Security-Policy gesendet wird, wenn die Policy Inline-Skripte per unsafe-inline erlaubt (ein nonce oder Hash, der das aufhebt, wird berücksichtigt) und wenn weder X-Frame-Options noch eine einschränkende frame-ancestors-Direktive Clickjacking verhindert. Mehrere Policies wertet er so aus wie der Browser. Diese Hinweise eröffnen keinen Incident; im kostenlosen Tool für HTTP-Header sind fehlende Header Warnungen.
Ob die übrigen Quellen sinnvoll eingeschränkt sind, bewertet DomainWarn nicht, und eine reine Report-Only-Policy zählt nicht als Policy. Ob tatsächlich Schadcode auf der Seite gelandet ist, prüft die Seitenintegrität (Incident „Website manipuliert (Spam, Miner oder Skimmer)“).
DomainWarn prüft das für alle deine Domains regelmäßig und meldet sich, wenn etwas fehlt oder sich ändert.