Reputation: 727
I've implemented CSP headers in my public site for security purposes, and have refactored the code to remove any instances of inline javascript like onclick=foo()
and <a href='javascript: bar()'
.
We've recently integrated with a 3rd party that injects code into the page. This is required on every public facing page. The issue is that their code contains a lot of inline javascript (same as mentioned above) and violates our CSP headers that disallow inline scripting.
My understanding is that if you have to add 'unsafe-inline'
for scripting you might as well not implement CSP at all due to the remaining security risks.
We're able to change the CSP headers per page, but since the code is required on every page it seems like it's all or nothing.
It doesn't look like you can allow 'unsafe-inline'
for only specific parts of a page, or we could just allow it for that section.
Is my only choice to allow 'unsafe-inline'
and defeat the whole point of CSP?
Upvotes: 5
Views: 4316
Reputation: 9727
You can use the nonce method to easily achieve this, without any need for unsafe-inline
. For example, Google has a guide on how to integrate Tag Manager using the nonce method, which sounds like an example of your use-case.
In short, using this method, the server generates a single-use unpredictable token and sets a CSP to allow it, and then uses the same token for the inline script. This way, the server determines exactly which inline scripts are acceptable.
Upvotes: 0
Reputation:
Is my only choice to allow
'unsafe-inline'
and defeat the whole point of CSP?
Most likely, yes. Sorry. But there might be a way around it.
If you know exactly what code is going to be injected into your site by the third-party script, you can whitelist that code in your CSP by its hash. For instance, if you knew that the following script would be injected:
<script>alert("hello world");</script>
you could calculate
> Base64(SHA256('alert("hello world");'))
"1tD3lYbOBFeMLrXs+T9Tv9xEgcMsVs032rlMyrYSa0c="
and add the following to your CSP:
script-src 'sha256-1tD3lYbOBFeMLrXs+T9Tv9xEgcMsVs032rlMyrYSa0c='
Of course, this will immensely bloat the size of your policy if multiple inline scripts are involved, and it won't work at all unless the content of those scripts is absolutely constant. So whether this is viable will depend significantly on your application, and what script you are trying to maintain compatibility with. (It may even change as that script is updated by the vendor…)
Upvotes: 4