Signatur
Beschreibung
Die schreibgeschützte Eigenschaft disposition des Interfaces SecurityPolicyViolationEvent zeigt, wie der Browser mit einer verletzten Content Security Policy (CSP) umgegangen ist. Der Wert ist immer einer von zwei Strings:
"enforce": Die Richtlinie wurde erzwungen und die Ressource oder Aktion (z. B. ein Inline-Skript oder ein externes Bild) wurde blockiert. Die Richtlinie kam über den HeaderContent-Security-Policyoder ein<meta http-equiv="Content-Security-Policy">."report": Die Richtlinie steht nur im Berichtsmodus (HeaderContent-Security-Policy-Report-Only). Die Verletzung wurde gemeldet, aber nicht blockiert.
Gebraucht wird die Eigenschaft vor allem beim schrittweisen Einführen einer CSP. Oft laufen dabei eine strenge Richtlinie im Report-Only-Modus und eine lockere erzwungene Richtlinie parallel. Mit disposition kann ein clientseitiger Listener für securitypolicyviolation beide Fälle auseinanderhalten. So lässt sich etwa nur bei echten Blockaden eine Fehlermeldung zeigen oder Telemetrie getrennt erfassen.
Das Ereignis wird auf dem Element ausgelöst, das die Verletzung verursacht hat, und steigt bis zu document und window auf. Deshalb registriert man den Listener meist global.
Rückgabewert
"enforce", wenn die Richtlinie erzwungen und die Aktion blockiert wurde; "report", wenn die Richtlinie nur im Report-Only-Modus aktiv ist.Beispiele
CSP-Verletzungen global protokollieren
document.addEventListener('securitypolicyviolation', (event) => {
const status = event.disposition === 'enforce' ? 'BLOCKIERT' : 'nur gemeldet';
console.warn(`[CSP ${status}] ${event.effectiveDirective}: ${event.blockedURI}`);
});
// Löst bei "img-src 'self'" eine Verletzung aus:
const img = new Image();
img.src = 'https://tracker.example.com/pixel.gif';
document.body.append(img);
Nur erzwungene Verletzungen an den Server melden
const sendeBericht = (event) => {
// Report-Only-Verletzungen sammelt der Browser per report-to bereits selbst
if (event.disposition !== 'enforce') return;
const payload = JSON.stringify({
directive: event.effectiveDirective,
blocked: event.blockedURI,
source: event.sourceFile,
line: event.lineNumber,
disposition: event.disposition
});
navigator.sendBeacon('/api/csp-telemetrie', payload);
};
window.addEventListener('securitypolicyviolation', sendeBericht);
Statistik über beide Modi führen
const zaehler = { enforce: 0, report: 0 };
const handler = ({ disposition }) => {
zaehler[disposition] += 1;
};
document.addEventListener('securitypolicyviolation', handler);
// Später, z. B. beim Verlassen der Seite:
setTimeout(() => {
document.removeEventListener('securitypolicyviolation', handler);
console.table(zaehler);
}, 5000);
// Wichtig · Fallstricke
- Es gibt kein
onsecuritypolicyviolation-Property, das überall zuverlässig funktioniert. Registriere den Listener mitaddEventListener('securitypolicyviolation', …). - Der Listener muss vor der Verletzung registriert sein. Verletzungen, die beim frühen Parsen auftreten, entgehen einem spät geladenen Skript. Für lückenlose Berichte eignen sich die Direktiven
report-tobzw.report-uribesser. - Laufen eine erzwungene und eine Report-Only-Richtlinie gleichzeitig, kann eine einzige Aktion zwei Ereignisse auslösen: eines mit
"enforce"und eines mit"report". - Das Ereignis dient nur der Diagnose. Es lässt sich nicht nutzen, um eine Blockade aufzuheben. Außerdem kann Schadcode Ereignisse vortäuschen (
new SecurityPolicyViolationEvent(...)). Clientseitige Telemetrie ist daher nicht vertrauenswürdig und muss serverseitig geprüft werden. - Eine Richtlinie per
<meta>-Tag kann nie"report"liefern, denn Report-Only wird nur als HTTP-Header unterstützt.