Content Security Policies In Sitecore

Have you ever created a site for a client and before going live, or regrettably after going live, a security audit reveals a rather glaring issue?

You’re missing or have an incorrect Content Security Policy (CSP) setup for the domain(s) you’re showing. It happens, sadly, to all of us. The important thing to realize is not only are there ways of reviewing your CSP but for Sitecore there’s a straight forward and very simple way of updating it.

When it comes to CSP, each version/setup of Sitecore has its own unique changes. If you're on standalone, you might need to adjust to support both the Content Management portion as well as the Content Delivery.

It also depends on how and who implemented it not to mention, whatever else you add to the site, e.g. Google Tag Manager, external fonts, 3rd party analytics, etc.

What Is Content Security Policy (CSP)?

As defined by the website,, CSP is:

"the name of a HTTP response header that modern browsers use to enhance the security of the document (or web page)"

And the purpose of it is really to reduce and or prevent Cross-Site Scripting (XSS) attacks on your website and prevent unauthorized scripts or harmful content from running on your site.

In other words, it’s absolutely something you want to have on your site. An example of a very simple CSP can be seen below where we essentially ONLY allow traffic originating from the same origin.

  <add name="Content-Security-Policy" value="default-src 'self'"/>    

Obviously this is a super strict CSP and while it does make your site secure, it will likely mean that 3rd party resources e.g. Google Tag Manager will fail to operate.

It could also mean that if you have css or JS hosted externally. You could theoretically list all the hosts under default-src but not all directives fall back to default-src.

Some directives, e.g. frame-src have even been deprecated to something called child-src.

The important thing to note is that while this is strict, it’s a GREAT way to start from scratch, though we suggest, do this In a dev or QA environment and not your production environment.

The Important Directives?

First, what is a directive? Directives are the segmentation of the types of content being authorized to run. Things like scripts, styles, images, fonts, iframes, etc. The ones that will snag you the most are the following:

Directive Description
Default-src This is the base directive. It defines the default policy for obtaining resources such as JavaScript, Images, CSS, Fonts, AJAX requests, Frames,
Script-src The directive for obtaining Javascript resources. More granular directives such as script-src-elem, script-src-attr, etc are also available but for most cases, script-src will suffice.
style-src The directive for obtaining CSS resources
img-src The directive for obtaining external images
Child-src / Frame-src The directives for supporting frame/iframe. Due to the nature of frame-src being deprecated and subsequently un-deprecated in CSP Level 3, it’s best for the time being to include both of these directives with identical values. Frame-src will fallback to child-src and then default-src
Font-src The directive for supporting fonts
media-src Supports video, audio tags

What Are Source Expressions?

So what is a source expression? Well in simple terms, it’s the part that comes directly after your directive. e.g. “” or ’self’ (pertaining to the host that your site is being delivered on. But there are a number of variants.

The important ones are below:

Source Expression Description
'self' Allows loading resources from the host origin
‘unsafe-inline' Allows the use of the style attribute, onclick, or script tags.
‘unsafe-eval' Allows for the use of things like “eval()” or “function()” as well as “settimeout()” or “setinterval()”. This is most commonly used in the script-src directive
’none' Prevent the loading of all resources
‘*' Allows all sources - use with caution

A full list of the source expressions can be found here:'s source list

How To Test Your CSP

Again, super simple. Just load up your favourite browser, and open up Inspect Mode or Developer Tools, so you can see the console of your site.

Now if you’re seeing messages that resemble the following, it means that your CSP is too strict or you’re missing a host or a directive. Things could be trying to fallback to a generic directive even.

Refused to load the script 'script-uri' because it violates the following Content Security Policy directive: "your CSP directive".

The message will be different in each browser, but the message is the same.

You may have several of these messages all identifying “outbound” calls your website is making, as such each “host” will need to be added to the headers of the site to enable them to run.

While all browsers react to CSP, they don’t all react in the same way.

Browsers like Chrome and Firefox are a bit more lenient where as browsers like Safari, won’t work unless the host value in your CSP contain the scheme (i.e. http:// or https:// ).

As such, it’s just better to incorporate the scheme to every host.

As it turns out, there are a number of great tools online to test out your CSP. Namely,

What Does A CSP Look Like?

Well there is a number of ways to create a CSP, even more when you add on a .NET layer or even Sitecore.

One of the simplest ways is to update your Web.config file in your wwwroot folder.

Here’s an example of a Content Security Policy you’d place in your Web.config file. One thing to note is you’ll see

For a Content Delivery environment, this is not necessary, but if you’re creating one for a Content Manager environment you will need it.

The pros about putting the CSP in your web.config file are that it’s one place to update and it’s done.

The cons are that you’re applying this CSP to your entire site. And you may or may not want that depending on the level of granularity your IT department might want as well as the content you’re serving.

Another con is that updating your CSP in your web.config file will undoubtedly cause some down time - unless you’re using something like Deployment Slots in Azure.

    <remove name="X-Powered-By" />
    <remove name="X-Content-Type-Options"/>
    <remove name="X-XSS-Protection"/>
    <remove name="Content-Security-Policy"/>
    <add name="X-XSS-Protection" value="1; mode=block"/>
    <add name="X-Content-Type-Options" value="nosniff "/>
    <add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self' 'unsafe-inline'; child-src 'self' 'unsafe-inline'; upgrade-insecure-requests;  block-all-mixed-content;"/>    

You’ll also have noticed some additional lines in the cutomHeaders section. You didn’t? Have another look.

While a Content Security Policy is one important step other headers, such as updating your X-XSS-Protection, X-Content-Type-Options are just as important as they help you to fully ensure your site is locked down to prevent unwanted guests.

It’s not uncommon to have a large Content Security Policy.

Another way would be do applying the CSP on a page by page approach.

The pros to this are that it’s granular, but the cons are that you have to educate your authors that when they add things like external images, styles, frames, they have to take the Content Security Policy into account.

Another pro here is that updating your CSP on a page by page level means no down time.

You can find an example of how this is done here:

It’s a bit more complex in terms of setup but does have benefits, namely one, that there wouldn't be an outage in deploying an update to the CSP and that it's controlled specifically on a page by page basis.

In The End...

Hopefully this helps you ensure your site is a bit more secure in the future and only in a couple of steps.

Additional Resource

So, still have more questions? Want to read up more on the Content Security Policy?

Hey, Developers!

We're on the look out for talented developers to join our team.

Think you have what it takes?

Meet David Austin

Development Team Lead


David is a decorated Development Team Lead with Sitecore Technology MVP and Coveo MVP awards, as well as Sitecore CDP & Personalize Certified. He's worked in IT for 25 years; everything ranging from Developer to Business Analyst to Group Lead helping manage everything from Intranet and Internet sites to facility management and application support. David is a dedicated family man who loves to spend time with his girls. He's also an avid photographer and loves to explore new places.

Connect with David