Signatur
Beschreibung
Die schreibgeschützte Eigenschaft sample des Wörterbuchs CSPViolationReport enthält einen kurzen Codeausschnitt der Ressource, die gegen die Content Security Policy verstoßen hat. Ein CSPViolationReport ist der Inhalt (body) eines Report-Objekts vom Typ "csp-violation". Solche Berichte werden über einen ReportingObserver gemeldet oder per Reporting-Endpoints-Header an einen Server geschickt.
Befüllt wird sample nur bei Inline-Verstößen, also bei blockierten <script>-Blöcken, Inline-Event-Handlern wie onclick="...", <style>-Blöcken und style-Attributen. Laut Spezifikation darf der Browser höchstens die ersten 40 Zeichen übernehmen. Bei eval()-Verstößen kann der Ausschnitt ebenfalls enthalten sein. Bei blockierten externen Ressourcen (z. B. <script src>) steht die Adresse in blockedURL und sample ist leer.
Wichtig: Der Ausschnitt wird nur übertragen, wenn die betroffene Direktive (z. B. script-src oder style-src) das Schlüsselwort 'report-sample' enthält. Fehlt es, ist sample immer ein leerer String. Der Ausschnitt hilft sehr bei der Fehlersuche: Man erkennt schnell, ob ein eigener Codeteil vergessen wurde, eine Browsererweiterung Code einschleust oder tatsächlich ein XSS-Versuch vorliegt.
Rückgabewert
"", wenn 'report-sample' fehlt oder keine Inline-Ressource betroffen ist.Beispiele
CSP-Header mit 'report-sample' und Reporting-Endpunkt
// Node.js / Express: CSP so setzen, dass Ausschnitte mitgeschickt werden
import express from 'express';
const app = express();
app.use((req, res, next) => {
res.setHeader('Reporting-Endpoints', 'csp-endpoint="/csp-reports"');
res.setHeader(
'Content-Security-Policy',
"script-src 'self' 'report-sample'; style-src 'self' 'report-sample'; report-to csp-endpoint"
);
next();
});
app.get('/', (req, res) => {
// Dieses Inline-Skript wird blockiert und erzeugt einen Bericht
res.send('<script>console.log("Hallo von einem Inline-Skript")</script>');
});
app.listen(3000);
Ausschnitt im Browser mit ReportingObserver auslesen
const observer = new ReportingObserver((reports) => {
for (const report of reports) {
const { effectiveDirective, sample, blockedURL } = report.body;
console.log(`Direktive: ${effectiveDirective}`);
console.log(`Blockiert: ${blockedURL}`);
console.log(`Ausschnitt: ${sample || '(kein Ausschnitt)'}`);
}
}, { types: ['csp-violation'], buffered: true });
observer.observe();
Berichte serverseitig auswerten und Ausschnitt protokollieren
import express from 'express';
const app = express();
// Die Reporting API sendet den Content-Type application/reports+json
app.post(
'/csp-reports',
express.json({ type: 'application/reports+json' }),
(req, res) => {
for (const report of req.body) {
if (report.type !== 'csp-violation') continue;
const { documentURL, effectiveDirective, sample } = report.body;
// Ausschnitt nur als Text protokollieren – niemals als HTML ausgeben!
console.warn(
`[CSP] ${documentURL} | ${effectiveDirective} | sample=${JSON.stringify(sample)}`
);
}
res.sendStatus(204);
}
);
app.listen(3000);
// Wichtig · Fallstricke
- Ohne
'report-sample'kein Ausschnitt: Das Schlüsselwort muss in der Direktive stehen, gegen die verstoßen wird, also inscript-srcbzw.style-srcoder den-elem/-attr-Varianten. Ein Eintrag nur indefault-srcreicht nicht, wenn eine speziellere Direktive gilt. - Höchstens 40 Zeichen: Der Ausschnitt wird abgeschnitten. Für eine eindeutige Zuordnung sollte man ihn mit
sourceFile,lineNumberundcolumnNumberkombinieren. - Sicherheit:
samplekann von Angreifern eingeschleusten Code enthalten. Den Wert in Admin-Oberflächen oder Log-Viewern daher nie ungeprüft perinnerHTMLausgeben, sonst entsteht eine zweite XSS-Lücke. Außerdem können im Ausschnitt personenbezogene oder sensible Daten stecken (z. B. Tokens in Inline-Skripten). Das ist beim Speichern von Protokollen zu beachten (DSGVO). - Browser-Kompatibilität:
ReportingObservermitcsp-violationundreport-towerden vor allem von Chromium-Browsern unterstützt. Für andere Browser zusätzlichreport-uriangeben: Dabei wird ein älteres JSON-Format mit dem Feldscript-samplegesendet. Im Dokument selbst liefert das Ereignissecuritypolicyviolationdenselben Wert überSecurityPolicyViolationEvent.sample. - Im Modus
Content-Security-Policy-Report-Onlywirdsamplegenauso befüllt. Damit lässt sich eine neue Richtlinie gefahrlos testen.