How do I prevent jQuery (in a local file) from violating my script-src CSP directive?

156 views Asked by At

A client wants us to add a script-src security policy to our software so that it satisfies their security standards. I have managed to create a relatively secure policy that still allows our code to run... EXCEPT I am getting a console error in my browser that says "Refused to execute inline script because it violates the following Content Security Policy directive" and that points to the file jquery-3.5.1.min.js. The error doesn't give me any more useful details. (It doesn't indicate a specific line in our code as being the problem.)

From what I can tell from the jQuery message boards, this sort of problem was fixed in jQuery several versions ago, so I have no idea why it's happening in this case.

I've also seen that some people access jQuery from a remote URL so the fix is to simply add that URL to script-src, but the current plan is to keep accessing jQuery from a local file.

I need to figure out how to stop getting this error without just making the code so unsafe that it defeats the purpose of using script-src in the first place (at which point the code would probably just fail the client's security scan again).

My current approach to the script-src policy has been to use a nonce. AFAIK, the nonce can't be generated by or brought into Web.config, so the only CSP in Web.config is this:

<add name="Content-Security-Policy" value="object-src 'none';" />

The Configuration() method inside Startup.cs calls another method called ConfigureNonce(), which is what creates the nonce and establishes the script-src policy:

       private void ConfigureNonce(IAppBuilder app)
        {
            app.Use((context, next) =>
            {
                var rng = new RNGCryptoServiceProvider();
                var nonceBytes = new byte[32];
                rng.GetBytes(nonceBytes);
                var nonce = Convert.ToBase64String(nonceBytes);
                context.Set("ScriptNonce", nonce);

                context.Response.Headers.Add("Content-Security-Policy",
                    new[] { string.Format("script-src 'self' 'unsafe-eval' xxxxxx yyyyyy http://localhost:* 'nonce-{0}'", nonce) });
                return next();
            });
        }
  1. 'xxxxxx' is the URL of an external provider we use for a certain widget.
  2. 'yyyyyy' is the URL of our help documentation.
  3. 'unsafe-eval' is apparently necessary because we use Kendo. [Thanks, Kendo...]
  4. 'localhost' is apparently necessary in development to stop getting a script-src violation due to Browser Link, but it will need to be removed when we go to production. [Thanks, Visual Studio...]

Finally, I have made a new helper file called NonceHelper.cs that just contains this:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    namespace dTIMSi.Helpers
    {
        public static class NonceHelper
        {
            public static IHtmlString ScriptNonce(this HtmlHelper helper)
            {
                var owinContext = helper.ViewContext.HttpContext.GetOwinContext();

                return new HtmlString(owinContext.Get<string>("ScriptNonce"));
            }
        }
    }

All of this enables me to see what web browser console errors I get for inline scripts (there are a lot), go to whatever line of code each error is indicating, and just add the nonce, like so:

    <script type="text/javascript" nonce="@Html.ScriptNonce()">
        //bla bla bla, doin' some inline script stuff
    </script>

Hopefully that all makes sense and is OK. But why am I getting an error on the jQuery file and how can I fix it?

0

There are 0 answers