How to handle CSP nonce for usercentries? (uc-block.bundle.js)

375 Views Asked by At

I'm using CSP; I made the changes for the policy on the server side, and then I'm using the nonce on the client side. It works for everything. I just have an issue with UserCentries. I still get the below error:

uc-block.bundle.js:1 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-cdbb69b0170fa85cd202dd223dc7de80' https://fonts.googleapis.com https://*.iadvize.com". Either the 'unsafe-inline' keyword, a hash ('sha256-gxqnKDxRDSXGSNnZ1pqKxuJyI+PHG6Tvsbz7z9B4+ZI='), or a nonce ('nonce-...') is required to enable inline execution.

And when I click on the error line in Chrome, it goes to the codes inside this file: enter image description here

It seems the issue is because of the style tag here, which doesn't have the nonce attribute.

I have a CspMiddleware and I handle the policy inside it. Here is the code for Policy:

public override async Task Invoke(IOwinContext context)
{
    var randomNonce = Shared.Extensions.Extensions.GenerateNonce();
    var isUmbracoRequest = context.Request.Uri.AbsolutePath.StartsWith("/umbraco");
    var policy = new[] {
        $"script-src 'self' {(isUmbracoRequest ? "'unsafe-inline'" : $"'nonce-{randomNonce}' 'strict-dynamic'")} {string.Join(" ", this._config?.ExternalUrls)}; " +
        $"style-src 'self' {(isUmbracoRequest ? "'unsafe-inline'" : $"'nonce-{randomNonce}'")} {string.Join(" ", this._config?.ExternalCssUrls)}; " +
        $"object-src 'self'; " +
        $"report-uri /umbraco/api/helper/CreateCSPReport"
    };

    if (!context.Response.Headers.ContainsKey("Content-Security-Policy")) context.Response.Headers.Add("Content-Security-Policy", policy);
    if (!context.Response.Headers.ContainsKey("X-Content-Security-Policy")) context.Response.Headers.Add("X-Content-Security-Policy", policy);
    if (!context.Response.Headers.ContainsKey("X-Webkit-CSP")) context.Response.Headers.Add("X-Webkit-CSP", policy);
    if (!isUmbracoRequest) context.Response.Headers.Add("X-Nonce", new[] { randomNonce });

    await Next.Invoke(context);
}

And on the razor page, I get the nonce and then set it for the UserCentries script:

@{
    var xNonce = HttpContext.Current.Response.Headers.GetValues("X-Nonce")?.First();
}

<script type="application/javascript" src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" nonce="@xNonce"></script>

When I inspect in the browser, I can see the nonce that has been added to this script, but still, I have the above error in the console. enter image description here

And here is how the CSP looks like in the http header: enter image description here

How can I handle the nonce for this specific script (uc-block.bundle.js)?

Thank you.

2

There are 2 best solutions below

5
pfx On BEST ANSWER

You can redefine the document.createElement function so that it not only creates the element, but also applies the nonce in case a style tag is being created, which is happening in that uc-block.bundle.js script.

That custom document.createElement function needs to be set up before the uc-block.bundle.js gets loaded.

Note that this is not without risk! Any referenced script marked with a nonce will be allowed to create an inline style element that will be executed.

For testing purposes I used below CSP.

script-src 'nonce-abc1234'; style-src 'nonce-abc1234'

@{
  var xNonce = "abc1234";  
  // Get from http header.  
  // HttpContext.Current.Response.Headers.GetValues("X-Nonce")?.First();
}
<script nonce="@xNonce">
  document.createElement = (function(func) {
    return function() {
      var element = func.apply(this, arguments);
      if (element.tagName.toLowerCase() == "style") 
      {
        element.setAttribute("nonce", "@xNonce");
      }
      return element;
    };
  })(document.createElement);
</script>

<script type="application/javascript" 
        src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" 
        nonce="@xNonce"></script>

The browsers developer tools shows that the style element has been added with a nonce (without revealing its value).

enter image description here

3
Halvor Sakshaug On

Your dependency is appending an inline style element to your document. It doesn't seem like there is any support for nonces in the dependency, so you'll have to resort to other solutions. You can try to add the mentioned hash to style-src. As there is a ternary operator you might have to add hashes for both, you can use https://report-uri.com/home/hash to calculate the hash if you are not easily reproducing both cases.

If the script output is dynamic, too many hashes will need to be added. Then you might need to resort to allowing 'unsafe-inline'. If you have restricted the rest of your CSP this isn't so bad after all, see https://scotthelme.co.uk/can-you-get-pwned-with-css/, but not all scanners and security testers will easily agree though.