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();
});
}
- 'xxxxxx' is the URL of an external provider we use for a certain widget.
- 'yyyyyy' is the URL of our help documentation.
- 'unsafe-eval' is apparently necessary because we use Kendo. [Thanks, Kendo...]
- '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?