Signatur
Beschreibung
Die Eigenschaft originalPolicy eines SecurityPolicyViolationEvent enthält den vollständigen Richtlinientext der Content Security Policy, die die Verletzung festgestellt hat. Das ist genau der Wert, der im HTTP-Header Content-Security-Policy bzw. Content-Security-Policy-Report-Only oder im <meta http-equiv="Content-Security-Policy">-Element angegeben wurde.
Wirklich nützlich ist das, wenn für ein Dokument mehrere Richtlinien gelten, z. B. eine durchgesetzte und eine reine Report-Only-Richtlinie, oder wenn verschiedene Header von Proxy, CDN und Anwendung zusammenkommen. Mit originalPolicy erkennst du, welche Richtlinie zugeschlagen hat. Zusammen mit violatedDirective/effectiveDirective, blockedURI und disposition bekommst du ein vollständiges Bild für Telemetrie und Fehlersuche.
Typischerweise liest du den Wert in einem Listener für das Event securitypolicyviolation aus, das auf document, window, Elementen oder im Worker-Kontext ausgelöst wird. Danach schickst du ihn etwa per navigator.sendBeacon() an einen eigenen Endpunkt, der CSP-Berichte sammelt.
Rückgabewert
"default-src 'self'; img-src 'self' https://cdn.example.com". Der Wert ist schreibgeschützt.Beispiele
Verletzende Richtlinie in der Konsole ausgeben
// CSP-Header z. B.: Content-Security-Policy: default-src 'self'; img-src 'self'
document.addEventListener('securitypolicyviolation', (event) => {
console.log('Richtlinie:', event.originalPolicy);
console.log('Direktive:', event.effectiveDirective);
console.log('Blockiert:', event.blockedURI);
});
// Löst eine Verletzung aus: externes Bild ist nicht erlaubt
const img = new Image();
img.src = 'https://evil.example.org/tracker.png';
document.body.append(img);
CSP-Verletzungen an eigenen Endpunkt melden
const reportViolation = (event) => {
const payload = {
policy: event.originalPolicy,
directive: event.effectiveDirective,
blocked: event.blockedURI,
disposition: event.disposition, // 'enforce' oder 'report'
source: `${event.sourceFile}:${event.lineNumber}:${event.columnNumber}`,
page: event.documentURI
};
const blob = new Blob([JSON.stringify(payload)], { type: 'application/json' });
navigator.sendBeacon('/api/csp-report', blob);
};
window.addEventListener('securitypolicyviolation', reportViolation);
Mehrere Richtlinien unterscheiden
// Durchgesetzte Richtlinie und Report-Only-Richtlinie parallel aktiv
const STRICT_MARKER = "'strict-dynamic'";
document.onsecuritypolicyviolation = (event) => {
const isStrictTest = event.originalPolicy.includes(STRICT_MARKER);
const label = isStrictTest ? 'Test-Richtlinie (strict-dynamic)' : 'Produktiv-Richtlinie';
console.warn(`[${label}] ${event.disposition}: ${event.effectiveDirective} -> ${event.blockedURI}`);
};
Event synthetisch erzeugen (z. B. für Tests)
const evt = new SecurityPolicyViolationEvent('securitypolicyviolation', {
documentURI: location.href,
violatedDirective: 'script-src',
effectiveDirective: 'script-src',
originalPolicy: "script-src 'self'",
disposition: 'enforce',
statusCode: 200
});
console.log(evt.originalPolicy);
// Wichtig · Fallstricke
- Der ganze Richtlinientext, nicht nur eine Direktive:
originalPolicyenthält die komplette Richtlinie. Welche Direktive verletzt wurde, steht ineffectiveDirective(bzw. im älterenviolatedDirective). - Mehrere Header: Gelten mehrere Richtlinien, bekommst du pro verletzter Richtlinie ein eigenes Event. Jedes enthält nur die Richtlinie, die es betrifft.
- Datenschutz: Die Richtlinie kann interne Hostnamen oder Nonces enthalten. Bevor du Berichte an Dritte schickst, entferne z. B.
'nonce-…'-Werte aus dem String. - Keine Events aus fremden Frames: Verletzungen in Cross-Origin-iframes sind im übergeordneten Dokument nicht sichtbar.
- Erlaubte Report-Ziele: Wenn deine CSP
connect-srceinschränkt, muss der Endpunkt fürsendBeacon()/fetch()erlaubt sein. Sonst erzeugt der Bericht selbst eine neue Verletzung. - Browser-Unterstützung: In allen modernen Browsern verfügbar, nicht im Internet Explorer. Die Header-Direktiven
report-uri/report-toarbeiten unabhängig vom JavaScript-Event.