Sitecore snuck in Content Security Policy!

Ages ago I wrote up a bit about how your public sites should consider implementing Content Security Policy because of all the hacks it can prevent. In a bit of frustrating irony, I was tripped up by a problem caused precisely because Sitecore have added some CSP headers to their own code. Google came up empty on this, so I’m documenting it for the next person who gets bitten.

The problem

I’ve been working on some research towards a brand new client project using Sitecore 10 on Docker. As part of my solution setup, I tried to add in the Sitecore Sidekick toolset, as I find it very useful for developers to pull down test content for their work. Having managed to work around the lack of a specific Sitecore 10 build for this at that point, I was hit with a very unexpected issue. Clicking the Sidekick icon got me this:

Chrome’s Content Security Policy code is blocking Sidekick’s window… Checking Dev Tools showed this error:

Refused to frame 'http://cm.whatever.localhost/' because it violates the following Content Security Policy directive: "default-src 'self' https://apps.sitecore.net". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.

And looking at the underlying markup I can see that the “window” on the Sitecore desktop is actually an iFrame:

So there are a few interesting things here:

  • Even without the CSP, this wouldn’t work well in Chrome
    If you look closely at the iFrame source, it’s an http:// request – but the overall page request is using https://. Chrome gets very unhappy at “mixed content” these days, so that would be a bad thing.
  • Containers mess with how you think HTTPS works
    The reason the mixed content thing happens is because in a container deployment, Sitecore uses Traefik as a reverse-proxy to do SSL termination. So you make an HTTPS request to the Traefik container, which deals with the SSL bit, and passes your HTTP request on to the Sitecore container over Docker’s internal networking. So when Sidekick tries to generate the “right” URL, it looks at the inbound request, and it sees “http“… And if you write code that processes URLs inside a container, you need to pay attention to the X-Forwarded-* headers – as they can tell you about the original request, before any proxies or SSL termination got in the way.
  • The CSP doesn’t have any frame-src config
    That means it’ll fall back to using the default-src setting – which is configured as “self” here. That means it will disallow any frame request that doesn’t come from the same scheme (https), port and host.

So where did that header come from, anyway?

This is the bit that confused me the most…

It turns out that sneakily, Sitecore pushed some config into V9.3 which writes out a basic CSP for any pages under /sitecore. This isn’t mentioned in the release notes for either V9.3 or V10, but it’s alluded to in this Knowledge Base article, which says that the lack of CSPs is “fixed” with V9.3.

My attempts at Google to work out how this was being done failed, but Jeff L’Heureux at Sitecore solved the conundrum for me. It’s been configured as a <customHeaders> setting in the site web.config:

So you can tweak it if you need to – if you need to allow certain other urls just update your web.config with some XDT before you release.

Hopefully this blog post is sort-of redundant already…

I discussed the core issue (that Sidekick wouldn’t work in a container with this CSP) with Jeff Darchuck, the creator of Sidekick, and he’s worked ou a fix so that Sidekick doesn’t trigger this issue any more. That should be available in version 1.5.7 and up on Nuget.

But it’s still possible you might hit this issue if you iFrame your own custom apps into a window on the Sitecore desktop. So maybe this will be of help…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.