I'm getting a bunch of errors in the developer console:
Refused to evaluate a string
Refused to execute inline script because it violates the following Content Security Policy directive
Refused to load the script
Refused to load the stylesheet
What's this all about? How does Content Security Policy work? How do I use the Content-Security-Policy
HTTP header?
Specifically, how to...
- ...allow multiple sources?
- ...use different directives?
- ...use multiple directives?
- ...handle ports?
- ...handle different protocols?
- ...allow
file://
protocol? - ...use inline styles, scripts, and tags
<style>
and<script>
? - ...allow
eval()
?
And finally:
- What exactly does
'self'
mean?
APACHE2 MOD_HEADERS
You could also enable Apache2 mod_headers, on Fedora it's already enabled by default, if you use Ubuntu/Debian enable it like this:
On Ubuntu/Debian you can configure headers in the file
/etc/apache2/conf-enabled/security.conf
Note: This is the bottom part of the file, only the last 3 entries are CSP settings.
The first parameter is the directive, the 2nd are the sources to be white-listed. I've added Google analytics and an adserver, which you might have. Furthermore I found that if you have aliases, e.g, www.example.com and example.com configured in Apache2 you should add them to the white-list as well.
Inline code is considered harmful, you should avoid it. Copy all the javascripts and css to separate files and add them to the white-list.
While you're at it you could take a look at the other header settings and install mod_security
Further reading:
https://developers.google.com/web/fundamentals/security/csp/
https://www.w3.org/TR/CSP/
The
Content-Security-Policy
meta-tag allows you to reduce the risk of XSS attacks by allowing you to define where resources can be loaded from, preventing browsers from loading data from any other locations. This makes it harder for an attacker to inject malicious code into your site.I banged my head against a brick wall trying to figure out why I was getting CSP errors one after another, and there didn't seem to be any concise, clear instructions on just how does it work. So here's my attempt at explaining some points of CSP briefly, mostly concentrating on the things I found hard to solve.
For brevity I won’t write the full tag in each sample. Instead I'll only show the
content
property, so a sample that sayscontent="default-src 'self'"
means this:1. How to allow multiple sources?
You can simply list your sources after a directive as a space separated list:
Note that there are no quotes around parameters other than the special ones, like
'self'
. Also, there's no colon (:
) after the directive. Just the directive, then a space-separated list of parameters.Everything below the specified parameters is implicitly allowed. That means that in the example above these would be valid sources:
These, however, would not be valid:
2. How to use different directives, what do they each do?
The most common directives are:
default-src
the default policy for loading javascript, images, CSS, fonts, AJAX requests, etcscript-src
defines valid sources for javascript filesstyle-src
defines valid sources for css filesimg-src
defines valid sources for imagesconnect-src
defines valid targets for to XMLHttpRequest (AJAX), WebSockets or EventSource. If a connection attempt is made to a host that's not allowed here, the browser will emulate a400
errorThere are others, but these are the ones you're most likely to need.
3. How to use multiple directives?
You define all your directives inside one meta-tag by terminating them with a semicolon (
;
):4. How to handle ports?
Everything but the default ports needs to be allowed explicitly by adding the port number or an asterisk after the allowed domain:
The above would result in:
As I mentioned, you can also use an asterisk to explicitly allow all ports:
5. How to handle different protocols?
By default, only standard protocols are allowed. For example to allow WebSockets
ws://
you will have to allow it explicitly:6. How to allow the file protocol
file://
?If you'll try to define it as such it won’t work. Instead, you'll allow it with the
filesystem
parameter:7. How to use inline scripts and style definitions?
Unless explicitly allowed, you can't use inline style definitions, code inside
<script>
tags or in tag properties likeonclick
. You allow them like so:You'll also have to explicitly allow inline, base64 encoded images:
8. How to allow
eval()
?I'm sure many people would say that you don't, since 'eval is evil' and the most likely cause for the impending end of the world. Those people would be wrong. Sure, you can definitely punch major holes into your site's security with eval, but it has perfectly valid use cases. You just have to be smart about using it. You allow it like so:
9. What exactly does
'self'
mean?You might take
'self'
to mean localhost, local filesystem, or anything on the same host. It doesn't mean any of those. It means sources that have the same scheme (protocol), same host, and same port as the file the content policy is defined in. Serving your site over HTTP? No https for you then, unless you define it explicitly.I've used
'self'
in most examples as it usually makes sense to include it, but it's by no means mandatory. Leave it out if you don't need it.But hang on a minute! Can't I just use
content="default-src *"
and be done with it?No. In addition to the obvious security vulnerabilities, this would leave it also won’t work as you'd expect. Even though some docs claim it allows anything, that's not true. It doesn't allow inlining or evals, so to really, really make your site extra vulnerable, you would use this:
... but I trust you won’t.
Further reading:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy