content-security-policyrequest-headers

content-security-policy allows any script tag without a nonce


I have a content-security-policy as follows in my response headers:

content-security-policy:
frame-ancestors 'none'; script-src 'self' 'nonce-ABC123' https://platform.twitter.com; object-src 'none';

This passes the security:

<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

And it also passes when I pass an empty nonce:

<script nonce="" async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Or an incorrect nonce:

<script nonce="incorrect" async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

If I replace src="https://platform.twitter.com/widgets.js" with a non-whitelisted source, eg src="https://forbidden.domain/widget.js", then the browser throws an error, except in the case where no nonce attribute is passed at all.

I don't believe this is the intended behaviour of the content-security-policy. Can anyone explain why passing no nonce attribute appears to allow any script tags through?


Solution

  • According to https://www.w3.org/TR/CSP/#script-pre-request it should be enoug to match either the nonce or the host as you do for platform.twitter.com.

    I'm not able to reproduce your finding for forbidden.domain without nonce tag for the latest Chrome and Firefox. I used the same script tags you have provided for platform.twitter.com and inserted https://forbidden.domain/widget.js instead. They are all blocked as expected.