In my previous article on security, I wrote about npm audit
and script integrity. Next up is Content Security Policy, or CSP for short.
This can either be added as response-headers on the server, or as a <meta>
-tag in the html.
I'm going to focus on the latter here.
A CSP will tell the webpage from which domains it will allow loading images, fonts, iframes, scripts etc. from:
<meta http-equiv="Content-Security-Policy" content="
default-src;
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src;
connect-src 'self';
media-src 'self';
object-src 'none';
child-src;
frame-src;
form-action;
base-uri;
manifest-src 'self';
">
It's one long string within the double quotes, so I've added line-breaks and tabs for clarity.
Each entry ends with a semicolon ;
Note the word 'self'. That's how you allow to run the various types from the same domain as the current document.
Scripts
To allow a script from an external site, maybe a delivery network such as unpkg.com, add unpkg.com
to the script-src
-part of the CSP:
script-src 'self' unpkg.com;
Cloudflare provides edge-caching and/or minification for assets, as well as a "Rocket Loader™", which will improve the paint-time for sites using JavsScript. I use it on my sites, but had to add this to my CSP:
script-src 'self' ajax.cloudflare.com;
A new entry is just a space, so combined, the current script-src
looks like this:
script-src 'self' unpkg.com ajax.cloudflare.com;
Google Fonts
For Google Fonts, you'll have to add entries to both font-src
and style-src
:
font-src fonts.gstatic.com;
style-src 'self' fonts.googleapis.com ;
YouTube
For YouTube, you need entries to frame-src
since it's iframe-based and to img-src
as it provides thumbnail images as well. CSP is not always easy, but it's the quickest way to add an extra layer of protection to your site!
frame-src *.youtube.com;
img-src 'self' img.youtube.com data:;
If you include the YouTube API as well, you must add it to the script-src
:
script-src *.youtube.com;
YouTube-videos works with these additions, but will occasionally generate errors for it's "doubleclick"-network and others. You can just ignore these, or add them to your CSP (if you trust them!):
script-src: https://www.googleadservices.com https://googleads.g.doubleclick.net https://www.google.com
img-src: https://www.google.com
frame-src: https://bid.g.doubleclick.net
Vimeo
Vimeo just need the frame-src
:
frame-src: *.vimeo.com
But if you want to use their API, add an entry to script-src
as well:
script-src: *.vimeo.com
Warning: Marketeers and SEO-people hate CSP's!
With a CSP in place, marketeers can no longer just add a cool new tracking-script via Google Tag Manager or similar. So: be prepared to hear a lot of complaints, unless you create a CMS-block, where they can add/remove CSP entries themselves!
Google Chrome supports many more CSP-entries than listed above. Unfortunately most of these doesn't work in Apple Safari, and can actually cause it to not parse JavaScript, so be sure to test in all browsers.
More info here:
https://content-security-policy.com/
And to help you create one:
https://report-uri.com/home/generate
Bonus: Add preconnect
While you're adding entries to your CSP, add a <link rel="preconnect">
-tag for the same entries to speed up communication between your site and these resources.
Example for "Google Fonts":
<link rel="preconnect" href="https://fonts.gstatic.com">
Thanks for reading!
Top comments (9)
No offence, but no marketeer or sales person will ever get my permission or an implementation to change any part of the CSP on their own.
I've worked for clients who removed a CSP-implementation or chose not to have a CSP, because marketeers wanted the freedom to implement any script via Google Tag Manager. In these cases, a CMS-block is much better than not having a CSP, although it's dangerous territory, and I agree with you.
Why am I not surprised that some clients literally come up with such decisions :-/
But under these circumstances I totally agree - better having them edit (a part of) the CSP than having none. I wonder if this would be implemented in a workflow, where the system (using include/exclude lists) or a human can review these edits, before actually publishing them.
Yes, any changes to the "CSP-config-block" can be previewed and verified before published.
Great article!
Hope it's ok, but would also like to recommend:
cspscanner.com/ - CSP scanner and evaluator
csp-evaluator.withgoogle.com/ - CSP evaluator by Google
rapidsec.com/ - Free report-uri & CSP generator.
More than OK - thanks!
Nice!
I'm writing some content about too, but i never finished :D
Hi Mads, It’s been a wonderful article.
My CSP headers url gets blocked, even it is mapped inside meta tag. Can you help me out with that!!! I don’t know where I messed the things.
Hi Amar, all CSP-errors are listed in the Console of Dev Tools. Here you’ll be able to see exactly what’s wrong.