What are Content Security Policy Headers?
Content Security Policy headers are used for restricting the content types and sources that browsers will load. They help to protect your site visitors by instructing their browsers to produce an error and prevent disallowed content from loading on the page.
Although it’s still up to the web browser to abide by the content policy headers, they help to proactively identify and block content that may be malicious, such as cross-site scripting (XSS) attacks.
Understanding the Content Security Policy Syntax
The syntax for the Content-Security-Policy header is quite straightforward. It’s simply a list of semicolon-separated directives and values.
Content-Security-Policy: <directive> <value>; <directive> <value>
A Single Directive with a Single Source
For example, defining a default source directive would look like this:
Content-Security-Policy: default-src example.com
A Single Directive with Multiple Sources
If multiple sources are being defined, they’re appended like this:
Content-Security-Policy: default-src example.com cdn.pagelyexample.com
When multiple directives are being defined, they’re separated by a semicolon:
Content-Security-Policy: default-src example.com; script-src images.example.com
Testing Content Security Policy Headers
Since it’s always a good idea to test changes as much as possible before fully deploying them, we recommend that you test your content security policy before deploying it to production. Thankfully, content security policy headers allow you to easily account for this with the Content-Security-Policy-Report-Only header.
Content-Security-Policy-Report-Only: default-src example.com
By defining your policies inside this header, you can receive warnings about any content that is outside of your content security policy, without causing the content to be outright blocked. It’s a great option when adding new rules to make sure that there are no unintentional side effects.
Common Content Security Policy Examples
Restricting Sources to Your Domain and CDN
This basic example simply allows loading content from your domain and Pagely’s PressCDN.
Content-Security-Policy: default-src example.com *.pcdn.co
Forcing HTTPS and Upgrading All Requests
Content-Security-Policy: default-src https:; upgrade-insecure-requests
Preventing Your Site From Being Loaded in an IFrame
If you want to stop anyone from loading your site within an iframe, you can do so from within your security policy.
Content-Security-Policy: frame-ancestors 'none'
Allowing Inline Scripts and Styles
When using various WordPress plugins and themes, you may be forced to allow inline styles and scripts to be executed. The following example addresses that need.
Content-Security-Policy: default-src example.com; script-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'
Allowing Images From All Sources
If you embed images from various different sources, especially when dealing with user-submitted content, you can allow all images while still keeping your other content restricted.
Content-Security-Policy: default-src example.com; img-src *
Allowing Google Fonts
To allow remote content from Google Fonts, you’ll need to allow the fonts and styles to be loaded from Google’s servers.
Content-Security-Policy: default-src example.com; font-src 'self' fonts.gstatic.com; style-src 'self' fonts.googleapis.com
Allowing Google Analytics
Employing a content security policy means that rules for remote tracking scripts, such as Google Analytics, will need to be put into place.
Content-Security-Policy: default-src example.com; script-src 'self' *.google-analytics.com; img-src 'self' *.google-analytics.com stats.g.doubleclick.net; connect-src 'self' *.google-analytics.com stats.g.doubleclick.net
Allowing Google Tag Manager
Similarly to the Google Analytics, Google Tag Manager will also require additional rules.
Content-Security-Policy: default-src example.com; script-src 'self' *.googletagmanager.com 'unsafe-inline' img-src 'self' *.googletagmanager.com
Allowing YouTube Video Embeds
YouTube loads content in various different ways and from a few different sources. You'll need to allow them if you're embedding YouTube videos on a site that's protected by a content security policy.
Content-Security-Policy: default-src example.com; media-src 'self' *.youtube.com *.youtube-nocookie.com; object-src 'self' *.youtube.com *.youtube-nocookie.com *.googlevideo.com *.ytimg.com; frame-src 'self' *.youtube.com *.youtube-nocookie.com