1

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 Answers 2

1
+50

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

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. I've tried it but it doesn't affect the script. I still have the same error.
Please share how above fragment looks when rendered at your side. Please also show how the CSP looks like in the http header.
I've updated the question. The above fragments have nonce on my side.
I put your script in the head, and it works now. Actually, I'm using the uc-block.bundle.js script in a partial view that is inside the body section. Yesterday, I just put your script before the bundle script in the partial view, but it didn't work. Today I tried to put it in the head section of master.cshtml. It works, and the error disappeared. Thanks a lot.
Well done! Glad to hear that.
0

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.

3 Comments

Is it possible to exclude the usercentries's script from the policy? I mean something like this: for usercentries just use "unsafe-inline" and for other externalUrls just use the "nonce"? Can we have this mix on the script-src? Thanks. I couldn't handle that. Do you have any idea?
You could try for w3.org/TR/CSP3/#strict-dynamic-usage, but I don't know if a script inserting a style would be covered. Apart from that I have no other solutions that already mentioned.
I'm already using 'strict-dynamic'. You can see it in my question. I've thought it would handle a script inserting a style, but it doesn't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.