Security Recommended
Collect reports of blocked content
Name a place for browsers to send policy errors with Reporting-Endpoints. Log those reports without any personal data.
How to do it
Send Reporting-Endpoints: csp-endpoint="/reports" and point report-to csp-endpoint at it. Also add report-uri /reports for browsers without report-to. Those send one application/csp-report object instead of a list. Accept both types, cap the body at 64 KB and put the endpoint behind the rate limit. Log only the type, path and directive, never the full address or the visitor's IP address.
Example
Reporting-Endpoints: csp-endpoint="/reports"
Content-Security-Policy: default-src 'self'; report-to csp-endpoint; report-uri /reports
// Express: accepts application/reports+json (a list) and application/csp-report (one object)
app.post('/reports', express.json({ type: ['application/reports+json', 'application/csp-report'], limit: '64kb' }), (req, res) => {
const reports = Array.isArray(req.body) ? req.body : [{ type: 'csp-violation', url: req.body['csp-report']?.['document-uri'], body: { effectiveDirective: req.body['csp-report']?.['effective-directive'] } }];
for (const r of reports) console.log(r.type, URL.parse(r.url ?? '')?.pathname, r.body?.effectiveDirective);
res.status(204).end();
});
# Flask: same two formats, body capped by MAX_CONTENT_LENGTH
from urllib.parse import urlsplit
app.config["MAX_CONTENT_LENGTH"] = 64 * 1024
@app.post("/reports")
def reports():
data = request.get_json(force=True, silent=True) or []
if isinstance(data, dict):
old = data.get("csp-report", {})
data = [{"type": "csp-violation", "url": old.get("document-uri", ""), "body": {"effectiveDirective": old.get("effective-directive")}}]
for report in data:
print(report.get("type"), urlsplit(report.get("url", "")).path, report.get("body", {}).get("effectiveDirective"))
return "", 204
How to check
Break the policy on a test page in two browsers. Each report appears in the log as one line with a path and a directive. A 1 MB POST answers 413.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers website playbook: https://agentwranglers.se/playbook/website/security/reporting-endpoints.