Signatur
Beschreibung
Das Ereignis securitypolicyviolation wird ausgelöst, sobald der Browser eine Ressource, ein Inline-Skript, einen eval()-Aufruf oder eine andere Aktion blockiert oder meldet, weil sie gegen die aktive Content Security Policy verstößt. Das gilt auch für Richtlinien im Modus Content-Security-Policy-Report-Only. In dem Fall wird nichts blockiert, das Ereignis kommt aber trotzdem.
Der Handler erhält ein SecurityPolicyViolationEvent. Die wichtigsten Eigenschaften sind violatedDirective bzw. effectiveDirective (die verletzte Direktive), blockedURI (die blockierte Ressource oder "inline"/"eval"), sourceFile, lineNumber, columnNumber, sample (die ersten Zeichen des blockierten Codes, falls 'report-sample' gesetzt ist), originalPolicy und disposition ("enforce" oder "report").
Das Ereignis wird zuerst am betroffenen Element ausgelöst (zum Beispiel an einem <img> oder <script>). Von dort steigt es bis zum Document auf (bubbles: true) und kann nicht abgebrochen werden. Ist kein Element betroffen, etwa bei eval oder connect-src, wird es direkt am Document ausgelöst. Einsatzzwecke sind das clientseitige Protokollieren von CSP-Verstößen, das Testen einer neuen Richtlinie im Report-Only-Modus und das Debuggen blockierter Drittanbieter-Skripte.
Registrieren kann man den Handler mit document.addEventListener("securitypolicyviolation", handler) oder über die Eigenschaft document.onsecuritypolicyviolation. Das Ereignis gibt es auch an Element, Window und in Workern (WorkerGlobalScope).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "securitypolicyviolation". |
|
| $handler Pflicht | (event: SecurityPolicyViolationEvent) => void | Callback, das bei jedem CSP-Verstoß mit einem SecurityPolicyViolationEvent aufgerufen wird. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, capture, passive oder signal zum späteren Entfernen. |
Beispiele
CSP-Verstöße in der Konsole protokollieren
document.addEventListener("securitypolicyviolation", (e) => {
console.warn("CSP-Verstoß:", {
direktive: e.effectiveDirective,
blockiert: e.blockedURI,
datei: e.sourceFile,
zeile: e.lineNumber,
modus: e.disposition
});
});
// Test bei CSP "img-src 'self'":
const img = new Image();
img.src = "https://fremd.example.com/bild.png";
document.body.append(img);
Verstöße gesammelt an einen eigenen Endpunkt senden
const buffer = [];
document.addEventListener("securitypolicyviolation", (e) => {
buffer.push({
directive: e.effectiveDirective,
blockedURI: e.blockedURI,
sample: e.sample,
source: `${e.sourceFile}:${e.lineNumber}:${e.columnNumber}`,
disposition: e.disposition,
time: Date.now()
});
});
// Beim Verlassen der Seite gesammelt senden
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden" && buffer.length) {
navigator.sendBeacon("/csp-log", JSON.stringify(buffer.splice(0)));
}
});
on-Property und Entfernen per AbortController
// Variante 1: on-Property (ersetzt einen vorherigen Handler)
document.onsecuritypolicyviolation = (e) => {
console.log("Blockiert:", e.blockedURI);
};
// Variante 2: addEventListener mit AbortSignal
const controller = new AbortController();
document.addEventListener(
"securitypolicyviolation",
(e) => console.log("Direktive:", e.violatedDirective),
{ signal: controller.signal }
);
// Später wieder abmelden
controller.abort();
document.onsecuritypolicyviolation = null;
Neue Richtlinie im Report-Only-Modus prüfen
// Header: Content-Security-Policy-Report-Only: script-src 'self'
document.addEventListener("securitypolicyviolation", (e) => {
if (e.disposition === "report") {
console.info(`Würde blockieren: ${e.blockedURI} (${e.effectiveDirective})`);
}
});
// Wichtig · Fallstricke
- Kein Schutz, nur eine Meldung: Das Ereignis ist nicht abbrechbar.
preventDefault()hat keine Wirkung, und blockiert wird ohnehin schon vom Browser. - Früh registrieren: Verstöße, die beim Parsen der Seite auftreten, bevor der Listener existiert, gehen verloren. Für eine vollständige Erfassung sollte man zusätzlich serverseitig per
report-to/report-urioder mit demReportingObservermelden lassen. - Datenschutz und Sicherheit:
blockedURIwird bei Weiterleitungen und fremden Ursprüngen oft auf den Origin gekürzt.sampleist nur mit'report-sample'gefüllt und auf 40 Zeichen begrenzt. Gemeldete Daten stammen vom Client und können gefälscht sein. Sie deshalb vor dem Speichern oder Anzeigen immer validieren, denn sonst droht XSS im Log-Dashboard. - Rauschen durch Browser-Erweiterungen: Erweiterungen fügen oft Skripte oder Styles ein, die Verstöße auslösen, etwa mit
blockedURIwiechrome-extensionodermoz-extension. Solche Einträge vor dem Senden herausfiltern. - Kompatibilität: Unterstützt von allen modernen Browsern, Firefox erst ab Version 63. Kein Support im Internet Explorer.
violatedDirectivegilt als veraltet, stattdesseneffectiveDirectiveverwenden. - Viele Verstöße, etwa in einer Schleife, können sehr viele Ereignisse erzeugen. Deshalb puffern oder drosseln, statt jedes Ereignis einzeln per Netzwerk zu senden.