Start · Sprachen · JavaScript · Referenz · Element: securitypolicyviolation

Element: securitypolicyviolation

Ereignis

Wird ausgelöst, wenn ein Element gegen die <code>Content-Security-Policy</code> der Seite verstößt, z. B. durch ein blockiertes Skript, Bild oder Inline-Style.

seit JavaScript Baseline: alle modernen Browser (Chrome 41+, Firef Kategorie: webapi

Signatur

element.addEventListener("securitypolicyviolation", handler)

Beschreibung

Das Ereignis securitypolicyviolation wird ausgelöst, sobald der Browser eine Ressource oder Aktion wegen der Content Security Policy (CSP) blockiert oder im Modus Content-Security-Policy-Report-Only nur meldet. Der Handler erhält ein SecurityPolicyViolationEvent mit Angaben dazu, welche Direktive verletzt wurde, welche URI blockiert wurde und an welcher Stelle im Quelltext das passiert ist.

Das Ereignis wird am betroffenen Element ausgelöst (etwa an einem <img> oder <script>), hat bubbles: true und composed: true und steigt deshalb bis zu document und window auf. In der Praxis registriert man den Listener meistens zentral an document, damit alle Verstöße auf der Seite erfasst werden. Verstöße ohne zugehöriges Element (z. B. durch eval() oder fetch()) werden direkt am document bzw. im Worker am globalen Objekt ausgelöst.

Typische Anwendungsfälle sind clientseitiges CSP-Monitoring und -Debugging, das Einsammeln von Verstößen und Weiterleiten an ein eigenes Logging-Backend (ergänzend zu report-uri/report-to) sowie das schrittweise Verschärfen einer Policy im Report-Only-Modus, ohne die Seite kaputtzumachen.

Außer über addEventListener() kann man den Handler auch über die Eigenschaft onsecuritypolicyviolation setzen, die an Elementen, document und window verfügbar ist. Das Ereignis kann nicht abgebrochen werden: Ein preventDefault() hebt die Blockierung nicht auf.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "securitypolicyviolation".
$handler Pflicht (event: SecurityPolicyViolationEvent) => void Callback, das ein SecurityPolicyViolationEvent erhält. Wichtige Eigenschaften: violatedDirective, effectiveDirective, blockedURI, documentURI, originalPolicy, disposition ("enforce" oder "report"), sourceFile, lineNumber, columnNumber, sample, statusCode, referrer.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie capture, once, passive oder signal.

Rückgabewert

Typ
void
Beschreibung
addEventListener() gibt undefined zurück. Der Handler bekommt ein SecurityPolicyViolationEvent übergeben.

Beispiele

Alle CSP-Verstöße zentral protokollieren

// Seite ausgeliefert mit: Content-Security-Policy: img-src 'self'
document.addEventListener('securitypolicyviolation', (event) => {
  console.warn('CSP-Verstoß:', {
    direktive: event.effectiveDirective,
    blockiert: event.blockedURI,
    modus: event.disposition,
    ziel: event.target.nodeName
  });
});

// Löst einen Verstoß aus, weil externe Bilder nicht erlaubt sind
const img = document.createElement('img');
img.src = 'https://example.com/bild.png';
document.body.append(img);
CSP-Verstoß: { direktive: 'img-src', blockiert: 'https://example.com/bild.png', modus: 'enforce', ziel: 'IMG' }

Verstöße an ein eigenes Monitoring-Backend senden

const reportViolation = (event) => {
  const payload = JSON.stringify({
    directive: event.effectiveDirective,
    blockedURI: event.blockedURI,
    documentURI: event.documentURI,
    source: `${event.sourceFile}:${event.lineNumber}:${event.columnNumber}`,
    sample: event.sample,
    disposition: event.disposition
  });
  // sendBeacon funktioniert auch beim Verlassen der Seite zuverlässig
  navigator.sendBeacon('/api/csp-reports', payload);
};

document.addEventListener('securitypolicyviolation', reportViolation);

Handler per on-Property setzen und Listener wieder entfernen

const script = document.createElement('script');

// Variante 1: on-Property direkt am Element
script.onsecuritypolicyviolation = (event) => {
  console.log('Skript blockiert:', event.blockedURI);
};

// Variante 2: einmaliger Listener, der danach wieder entfernt wird
const onViolation = (event) => {
  console.log('Erster Verstoß:', event.violatedDirective);
  document.removeEventListener('securitypolicyviolation', onViolation);
};
document.addEventListener('securitypolicyviolation', onViolation);

script.src = 'https://cdn.fremd.example/lib.js';
document.head.append(script);
Skript blockiert: https://cdn.fremd.example/lib.js Erster Verstoß: script-src-elem

Report-Only-Modus zum Testen einer neuen Policy

// Header: Content-Security-Policy-Report-Only: style-src 'self'
const violations = new Map();

document.addEventListener('securitypolicyviolation', (event) => {
  if (event.disposition !== 'report') return;
  const key = `${event.effectiveDirective} → ${event.blockedURI}`;
  violations.set(key, (violations.get(key) ?? 0) + 1);
});

// Nach einer Weile auswerten
setTimeout(() => console.table([...violations]), 5000);

// Wichtig · Fallstricke

  • Nicht abbrechbar: preventDefault() hat keine Wirkung, die blockierte Ressource bleibt blockiert. Das Ereignis dient nur zur Beobachtung.
  • Listener früh registrieren: Verstöße, die beim Parsen des HTML auftreten, bevor dein Skript läuft, werden nicht mehr erfasst. Den Listener deshalb möglichst früh im <head> setzen (mit Nonce oder Hash, damit er selbst CSP-konform ist).
  • Datenschutz/Sicherheit: blockedURI wird bei fremden Ursprüngen oft auf den Ursprung gekürzt, und sample enthält höchstens die ersten 40 Zeichen und nur, wenn die Policy 'report-sample' enthält. Beim Weitersenden an ein Backend keine sensiblen Daten (Tokens in URLs) ungefiltert speichern.
  • Kein Ersatz für serverseitiges Reporting: Ein Angreifer mit Skriptzugriff kann clientseitige Listener manipulieren. Für verlässliches Monitoring zusätzlich report-to/report-uri verwenden.
  • Ohne Element: Verstöße durch eval(), new Function(), fetch() oder WebSockets werden am document ausgelöst, nicht an einem Element. In Web Workern steht das Ereignis am globalen Worker-Objekt zur Verfügung.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt; der Internet Explorer unterstützt es nicht. Ältere Browser liefern teils violatedDirective statt der genaueren effectiveDirective-Werte wie script-src-elem.