-.- --. .-. --..

Using CSP in report-only and enforcement mode

I recently came across this strategy which uses the standardised Content Security Policy for both enforcement and script monitoring on a web page for security. We use CSP for enforcement already, but I was under the assumption that report-only mode and enforcement mode are exclusive. That is, if the Content-Security-Policy header was used with a few rules, I thought the Content-Security-Policy-Report-Only can’t be used; or perhaps it doesn’t work if we send both. But, in hindsight, this was wrong. For example, let’s say a page returns the following headers, and there’s an <img> tag on this page trying to load images from example.com.

Content-Security-Policy: default-src 'self' images.kgrz.io; report-uri: /report-block
Content-Security-Policy-Report-Only: default-src 'self'; report-uri: /report-only

This CSP setting ensures resources only from images.kgrz.io are successfully loaded onto the page. I had always had the implicit understanding that the image load will be blocked, and a report sent out to /report-block path. But this is not the case: there’ll be two reports sent-out: one to /report-block, and one to /report-only.

The sample application that demonstrates this example is hosted at /apps/csp. You may have to have a modern-ish website to use this since I’m using no build pipeline for the JS that’s used on the page. (Anything that [supports <script type="module">][module_can_i_use])