Start · Sprachen · JavaScript · Referenz · WorkerGlobalScope: securitypolicyviolation

WorkerGlobalScope: securitypolicyviolation

Ereignis

Wird im globalen Scope eines Workers ausgelöst, wenn eine Content Security Policy (CSP) verletzt wird, z. B. durch ein blockiertes <code>fetch()</code> oder <code>importScripts()</code>.

seit JavaScript Baseline: alle modernen Browser (Chrome, Firefox, Kategorie: webapi

Signatur

self.addEventListener("securitypolicyviolation", handler)

Beschreibung

Das Ereignis securitypolicyviolation wird am WorkerGlobalScope (also an self in einem Dedicated, Shared oder Service Worker) ausgelöst, wenn eine Aktion im Worker gegen die für ihn gültige Content Security Policy verstößt. Typische Auslöser sind blockierte Netzwerkanfragen (connect-src), per importScripts() geladene Skripte (script-src/worker-src) oder eval() ohne 'unsafe-eval'.

Der Handler erhält ein SecurityPolicyViolationEvent mit Details wie blockedURI, violatedDirective, effectiveDirective, originalPolicy, disposition ("enforce" oder "report"), sourceFile, lineNumber und columnNumber. Damit lassen sich CSP-Verstöße clientseitig protokollieren, an einen eigenen Endpunkt melden oder im Entwicklungsbetrieb schnell diagnostizieren.

Registrierung erfolgt entweder über self.addEventListener("securitypolicyviolation", handler) oder über die Eigenschaft self.onsecuritypolicyviolation = handler. Das Ereignis ist nicht abbrechbar; es informiert lediglich – die Blockierung selbst ist bereits erfolgt (bzw. im Modus Content-Security-Policy-Report-Only nur gemeldet).

Welche CSP für einen Worker gilt, hängt von seiner Herkunft ab: Worker aus eigenen Skript-URLs erhalten die CSP aus den HTTP-Headern der Worker-Skript-Antwort; Worker aus blob:- oder data:-URLs erben in der Regel die Richtlinie des erzeugenden Dokuments.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "securitypolicyviolation".
$handler Pflicht (event: SecurityPolicyViolationEvent) => void Callback, der mit einem SecurityPolicyViolationEvent aufgerufen wird. Alternativ als self.onsecuritypolicyviolation zuweisbar.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal (zum Entfernen per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener() gibt nichts zurück. Der Handler erhält ein SecurityPolicyViolationEvent.

Beispiele

CSP-Verstöße im Worker per addEventListener protokollieren

// worker.js – ausgeliefert mit Header:
// Content-Security-Policy: connect-src 'self'
self.addEventListener('securitypolicyviolation', (event) => {
  console.warn('CSP-Verstoß im Worker:', {
    blockiert: event.blockedURI,
    direktive: event.effectiveDirective,
    modus: event.disposition
  });
});

// Diese Anfrage verstößt gegen connect-src 'self'
fetch('https://api.fremd.example/daten').catch((err) => {
  console.error('fetch fehlgeschlagen:', err.message);
});
CSP-Verstoß im Worker: { blockiert: 'https://api.fremd.example/daten', direktive: 'connect-src', modus: 'enforce' } fetch fehlgeschlagen: Failed to fetch

Verstöße an den Haupt-Thread melden (on-Property)

// worker.js
self.onsecuritypolicyviolation = (event) => {
  self.postMessage({
    typ: 'csp-violation',
    blockedURI: event.blockedURI,
    directive: event.violatedDirective,
    source: `${event.sourceFile}:${event.lineNumber}`
  });
};

try {
  importScripts('https://cdn.unerlaubt.example/lib.js');
} catch (e) {
  self.postMessage({ typ: 'fehler', text: e.name });
}

// main.js
const worker = new Worker('worker.js');
worker.addEventListener('message', ({ data }) => {
  if (data.typ === 'csp-violation') {
    console.log('Worker meldet CSP-Verstoß:', data.directive, data.blockedURI);
  }
});
Worker meldet CSP-Verstoß: script-src https://cdn.unerlaubt.example/lib.js

Verstöße gebündelt an eigenen Endpunkt senden und Listener entfernen

// worker.js
const controller = new AbortController();
const puffer = [];

const onViolation = (event) => {
  puffer.push({
    blockedURI: event.blockedURI,
    directive: event.effectiveDirective,
    sample: event.sample,
    zeit: Date.now()
  });
};

self.addEventListener('securitypolicyviolation', onViolation, {
  signal: controller.signal
});

// Alle 10 Sekunden senden
const intervall = setInterval(async () => {
  if (puffer.length === 0) return;
  const batch = puffer.splice(0);
  await fetch('/csp-report', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(batch)
  });
}, 10_000);

// Beim Herunterfahren aufräumen
self.addEventListener('message', ({ data }) => {
  if (data === 'stop') {
    controller.abort(); // entspricht removeEventListener
    clearInterval(intervall);
    self.close();
  }
});

// Wichtig · Fallstricke

  • Endlosschleife vermeiden: Wird der Report selbst per fetch() an einen Endpunkt gesendet, der ebenfalls gegen connect-src verstößt, löst das erneut das Ereignis aus. Den Report-Endpunkt daher immer erlauben (z. B. 'self').
  • Nicht abbrechbar: preventDefault() hat keine Wirkung; die Ressource bleibt blockiert.
  • Welche CSP gilt? Worker aus regulären URLs nutzen die CSP-Header der Worker-Skript-Antwort, nicht die des Dokuments. blob:-/data:-Worker erben die Richtlinie des Erzeugers. Das führt häufig zu Verwirrung, wenn Verstöße „nicht auftauchen“.
  • Datenschutz/Sicherheit: blockedURI wird bei Cross-Origin-Weiterleitungen teils auf den Ursprung gekürzt; sample ist nur gefüllt, wenn die Richtlinie 'report-sample' enthält. Gemeldete Daten nicht ungeprüft in HTML einsetzen (XSS).
  • Report-Only: Bei Content-Security-Policy-Report-Only wird das Ereignis mit disposition === "report" ausgelöst, ohne dass etwas blockiert wird – ideal zum Testen neuer Richtlinien.
  • Kompatibilität: In aktuellen Chromium-, Firefox- und Safari-Versionen unterstützt; ältere Browser feuern das Ereignis nur am Document, nicht im Worker. Als Ergänzung bietet sich die serverseitige report-to-Direktive bzw. die Reporting API (ReportingObserver) an.