Fixing mixed content with CSP

As more and more sites are migrating to HTTPS, one of the biggest problems that will need solving is tracking down all of your HTTP resources to avoid mixed content warnings. Whilst this could sound like a daunting task, especially on sites with a large amount of content, CSP can very easily reduce that burden. Here's how!

Content Security Policy

CSP is a mechanism that allows site operators to whitelist an approved set of sources for content on their pages. You can specify where images are allowed to be loaded from, where scripts and styles can loaded from and much, much more. Whilst CSP is aimed at specifying particular sources for your resources to be loaded from, say your favourite CDN, you can be much more broad and simply specify that all resources must be loaded over https, for example. My blog, Content Security Policy - An Introduction, gives an overview of CSP and exactly what it is and does and you can also refer to my CSP Cheat Sheet if you need a quick reference on particular directives or features.

Seeking out HTTP resources

I've recently covered what might seem like a very similar topic in my blog titled Migrating from HTTP to HTTPS? Ease the pain with CSP and HSTS!, but that focused more on forcing the use of HTTPS for resources with certain CSP directives and HSTS. Whilst that works perfectly well for browsers that are CSP and HSTS compliant, it doesn't actually work to resolve the underlying issue that you're referencing resources over an insecure scheme on a secure page. The method I'm about to cover was recently covered at the Chrome Developer Summit by Emily Stark from the Chrome Security Team and you can see what Emily has to say about CSP in her excellent session on Deploying HTTPS: The Green Padlock and Beyond, right here:

There are many ways that we can use the policy example that Emily provided and many situations that we can use it in. For example, once you can serve your resources over HTTPS, you can begin to update references to them but not actually redirect the user to HTTPS pages. If you issue the CSP to default to HTTPS, it's only for resources on the page, you can identify them all before you ever make the switch. Even if you already have a CSP deployed on your site, you can issue the Report Only version of the header alongside your existing policy and still gather all of the necessary information to identify all of your HTTP resources. It will help you find any resource referenced over an insecure scheme, be that self hosted or 3rd party hosted resources.

Content-Security-Policy-Report-Only: default-src https:; report-uri

Reporting is key

The crucial part to all of this is the ability to send reports when something violates the CSP. In Report Only mode the browser will send these reports but not take any action that will break your page so there's nothing to worry about. The only problem is that CSP can be very noisy at the best of times but a policy like the one above is really going to ramp up some serious inbound reports. If you have a page with 25 resources on it loaded over HTTP, then that's going to generate 25 POST requests with a JSON report payload for every single page load! This is where my CSP reporting service,, can help you and a big thanks to Emily for giving it a mention! logo

If you head over to you can sign up for a free account and start collecting reports right away. All you need to do is put your own custom reporting address into your CSP and reports will be sent to your account, it's that simple! Don't forget, on the Setup page you can create your own 'vanity' reporting address like mine so instead of a random token, you can have whatever you like (within reason).


set a custom report-uri

your own report-uri

Analysing the reports

As you can imagine, analysing the sheer quantity of reports that are generated by a CSP deployment like this could be quite tricky, especially given the amount of noise. To help reduce the amount of noise, there are a selection of filters in the Settings page that I strongly advise you enable. You should also specify the host that you're expecting reports for so that additional unwanted reports can be discarded.

report-uri filters

With these enabled, and some nice aggregation and graphing of reports, it becomes quite easy to spot problems in your pages. Take this for example:

http image

Here we can see that in the last hour I've had 1,239 reports of the use of a http image on the homepage. You could now raise a bug or open a ticket as per your normal process to have the reference updated to load the resource over HTTPS. Initially you're probably going to get a lot of these kind of things reported depending on how much leg work you did before you deployed the CSP, but the great advantage here is that you don't need to go around hunting for every last resource. You're effectively turning the browser of each visitor into a test tool that will scrutinise the page for any HTTP resources and then notify you of what they find. This could apply to a global site with geographically diverse content, perhaps mobile and desktop versions of a site and even sites in different languages. There could be a huge surface area that needs investigating and CSP is going to help massively. Even if everything is converted, there's absolutely no harm in keeping the CSP in place for the odd occasion when a resource might slip in to production and be referenced over http.

csp report graph

If you do see a sudden and unexpected spike in any particular area you can immediately start to investigate why because with CSP you actually know it's happening. It's not a case of waiting for users to speak up on Twitter that a page is broken or for a QA to pick up a bug, as soon as the problem hits the page, the browser will start sending CSP reports. With that, it's also worth mentioning that deploying CSP into your test or pre-production environments could be a great early warning system.


CSP is an incredibly powerful feature and it is tremendously flexible. You can configure it to do a great deal more things than I've covered in this blog or you can keep it as simple as you like. Starting out in Report Only mode protects you from causing any disasters and the ability to send reports and be notified of issues in near real-time can add real value. If you want to give CSP a try I've built a range of tools that will help you build and analyse your CSP that you can find here, and of course, you should sign up for a free account over at to implement reporting and get real-time feedback from your site.

Author image
About Scott Helme