Signatur
Beschreibung
Die Eigenschaft effectiveDirective eines SecurityPolicyViolationEvent sagt dir, welche Direktive der Content Security Policy eine Ressource oder Aktion blockiert (bzw. im Report-Only-Modus nur gemeldet) hat. Der Wert ist ein Direktivenname wie script-src-elem, style-src-attr, img-src, connect-src oder frame-ancestors.
Wichtig ist der Unterschied zu violatedDirective: Greift eine spezifische Direktive nicht, weil sie in der Policy fehlt, fällt der Browser auf eine allgemeinere zurück, etwa default-src. effectiveDirective nennt trotzdem die Direktive, die eigentlich zuständig gewesen wäre (z. B. img-src). So weißt du genau, welche Direktive du ergänzen oder lockern musst. violatedDirective ist ein veralteter Alias. Moderne Browser liefern dort meist denselben Wert.
In der Praxis wertest du die Eigenschaft in einem Listener für das Ereignis securitypolicyviolation aus, das auf document, Element oder in Workern auf WorkerGlobalScope ausgelöst wird. Typische Einsatzfälle: CSP-Verstöße clientseitig sammeln und an einen Logging-Endpunkt schicken, eine neue Policy im Modus Content-Security-Policy-Report-Only ausrollen und Verstöße nach Direktive gruppieren, oder beim Debuggen gezielt Inline-Skripte und Inline-Styles finden.
Rückgabewert
"script-src-elem", "img-src" oder "connect-src". Der Wert ist schreibgeschützt.Beispiele
Verstöße per addEventListener protokollieren
// Policy z. B.: Content-Security-Policy: default-src 'self'
document.addEventListener('securitypolicyviolation', (event) => {
console.log('Direktive:', event.effectiveDirective);
console.log('Blockiert:', event.blockedURI);
console.log('Quelle:', `${event.sourceFile}:${event.lineNumber}`);
});
// Löst einen Verstoß aus (externes Bild, nicht 'self')
const img = new Image();
img.src = 'https://cdn.example.com/logo.png';
document.body.append(img);
Verstöße nach Direktive gruppieren und gebündelt melden
const violations = new Map();
document.addEventListener('securitypolicyviolation', ({ effectiveDirective, blockedURI, disposition }) => {
const list = violations.get(effectiveDirective) ?? [];
list.push({ blockedURI, disposition }); // disposition: 'enforce' | 'report'
violations.set(effectiveDirective, list);
});
// Beim Verlassen der Seite gebündelt an den Server senden
document.addEventListener('visibilitychange', () => {
if (document.visibilityState !== 'hidden' || violations.size === 0) return;
const payload = JSON.stringify(Object.fromEntries(violations));
navigator.sendBeacon('/csp-log', payload);
violations.clear();
});
Unterschied zu violatedDirective und synthetisches Event
const event = new SecurityPolicyViolationEvent('securitypolicyviolation', {
effectiveDirective: 'script-src-elem',
violatedDirective: 'script-src-elem',
originalPolicy: "default-src 'self'",
blockedURI: 'https://evil.example/x.js',
disposition: 'enforce',
statusCode: 200
});
console.log(event.effectiveDirective);
console.log(event.originalPolicy);
// Schreibgeschützt: Zuweisung wird ignoriert
event.effectiveDirective = 'img-src';
console.log(event.effectiveDirective);
// Wichtig · Fallstricke
- Fallback-Direktiven: Wird ein Verstoß über
default-srcdurchgesetzt, meldeteffectiveDirectivetrotzdem die spezifische Direktive (z. B.img-src). Wenn du mit diesem Namen in der Policy suchst, findest du ihn dort unter Umständen nicht. - Granulare Direktiven: Neuere Browser unterscheiden zwischen
script-src-elemundscript-src-attrbzw.style-src-elemundstyle-src-attr. Ältere Versionen melden stattdessen nurscript-srcoderstyle-src. Beim Auswerten solltest du beide Varianten berücksichtigen. - Kein Ereignis ohne CSP: Das Event wird nur ausgelöst, wenn eine Policy per HTTP-Header oder
<meta http-equiv=\"Content-Security-Policy\">aktiv ist. Einige Direktiven, etwaframe-ancestors,report-uriundsandbox, werden in<meta>ignoriert. - Datenschutz und Sicherheit:
blockedURIkann bei Weiterleitungen über Origins hinweg gekürzt sein. Die gemeldeten Daten können von Angreifern oder Browser-Erweiterungen stammen. Validiere deshalb alles, was du an einen Logging-Endpunkt sendest, serverseitig und gib es niemals ungeprüft perinnerHTMLaus (XSS-Gefahr). - Den Listener solltest du so früh wie möglich registrieren, am besten in einem Skript im
<head>. Verstöße, die vorher auftreten, bekommst du sonst nicht mit. - Für serverseitiges Sammeln ohne JavaScript eignen sich die Direktive
report-tound die Reporting API. Deren Berichte enthalten dasselbe Feld alseffectiveDirective.