More Content Security Policy with report-to
Sending even more Content Security Policy (CSP) violation reports with report-to
, asynchronously and possibly grouping more reports together. Read general CSP reporting description for more details.
The CSP response header:
Content-Security-Policy: default-src 'none'; img-src 'self' https://www.michalspacek.cz; script-src 'nonce-9qO34X33CJ+cDBUrEV1+eVL8' 'self' 'report-sample'; style-src 'self' 'nonce-9qO34X33CJ+cDBUrEV1+eVL8'; form-action 'self'; report-to default
default-src
: what's allowed by default, includes images, fonts, JavaScript and more-
img-src
: where to load images from, overridesdefault-src
for images'self'
means current URL's origin (scheme + host + port)
-
script-src
: what JavaScript is allowed to be executed'nonce-9qO34X33CJ+cDBUrEV1+eVL8'
meansscript
elements withnonce="9qO34X33CJ+cDBUrEV1+eVL8"
attribute'report-sample'
instructs the browser to include the first 40 characters of the blocked JavaScript in the report
style-src
: allowed CSS sourcesform-action
: where it's allowed to submit forms, not part ofdefault-src
report-to
: name of the group where to send violation reports to
The Report-To
response header:
Report-To: {"group":"default","max_age":1800,"endpoints":[{"url":"https://dirty.has.report/report"}],"include_subdomains":true}
group
: the name of the group, the same as in the CSP header in thereport-to
directivemax_age
: how long the browser should use the endpoint and report errors to it-
endpoints
: reporting endpoint configuration, can specify multiple endpoints but reports will be sent to just one of themurl
: where to send reports to, must behttps://
, otherwise the endpoint will be ignored
Load any image
<script nonce="9qO34X33CJ+cDBUrEV1+eVL8">
document.getElementById('prompt-image').onclick = function() {
const url = prompt('Enter a URL to be used for an image', 'https://');
if (url) {
new Image().src = url;
alert('Tried loading an image from ' + url);
}
}
</script>
- Allowed or blocked depending on what URL you enter, only some images are allowed to load, see the CSP header above
- Check your reports (can take some time before the browser sends the report) – if blocked, a report will be sent
… any JavaScript file
<script nonce="9qO34X33CJ+cDBUrEV1+eVL8">
document.getElementById('prompt-javascript').onclick = function() {
const url = prompt('Enter a URL to load a JS file from', 'https://');
if (url) {
const script = document.createElement('script');
script.src = url;
document.getElementById('prompt-javascript').insertAdjacentElement('afterend', script);
alert('Tried loading a JS file from ' + url);
}
}
</script>
- Allowed or blocked depending on what URL you enter, only some JS is allowed to load, see the CSP header above
- Check your reports (can take some time before the browser sends the report) – if blocked, a report will be sent
… any CSS file
<script nonce="9qO34X33CJ+cDBUrEV1+eVL8">
document.getElementById('prompt-css').onclick = function() {
const url = prompt('Enter a URL to load a CSS file from', 'https://');
if (url) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.getElementById('prompt-javascript').insertAdjacentElement('afterend', link);
alert('Tried loading a CSS file from ' + url);
}
}
</script>
- Allowed or blocked depending on what URL you enter, only some CSS is allowed to load, see the CSP header above
- Check your reports (can take some time before the browser sends the report) – if blocked, a report will be sent
Submit a form anywhere
With form-action
, you can limit where forms on your page can be submitted,
so if an attacker would inject a fake form or would change the action
of your existing form, the browser wouldn't submit it.
Please note that form-action
is not part of the default-src
fallback, and needs to be explicitly specified if you want to limit where forms are to be submitted.
<script nonce="9qO34X33CJ+cDBUrEV1+eVL8">
document.getElementById('prompt-form').onclick = function() {
const url = prompt('Enter a URL where to submit a form to', 'https://');
if (url) {
const form = document.getElementById('submitForm');
if (form) {
form.setAttribute('action', url);
form.submit();
} else {
const form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('class', 'hidden');
form.setAttribute('action', url);
form.setAttribute('id', 'submitForm');
const text = document.createElement('input');
text.setAttribute('type', 'text');
text.setAttribute('value', 'text value');
form.appendChild(text);
const hidden = document.createElement('input');
hidden.setAttribute('type', 'hidden');
hidden.setAttribute('value', 'hidden value');
form.appendChild(hidden);
document.getElementById('prompt-form').insertAdjacentElement('afterend', form);
form.submit();
}
alert('Submitted a form to ' + url);
}
}
</script>
- Allowed or blocked depending on what URL you enter, forms are not allowed to be submitted anywhere, see the CSP header above
- Check your reports (can take some time before the browser sends the report) – if blocked, a report will be sent
Related specs & documents
- Content Security Policy Level 3 Working Draft
- Content Security Policy Level 2
- Content Security Policy 1.0 (discontinued)
- Reporting API Working Draft
- Reporting API Editor's Draft (which will evolve into a Working Draft, followed by a Recommendation eventually)
-
Notable changes in the Editor's Draft are switching to structured headers (
Reporting-Endpoints
instead ofReport-To
) and moving out concrete reports into the following separate Draft Community Group Reports: Crash Reporting, Deprecation Reporting, Intervention Reporting