In case you’re enthusiastic about Sizzling Reload like me AND you additionally need an “A” grade from SecurityHeaders.com (actually, go do this now) then you’ll be taught in a short time about Content material-Safety-Coverage headers. You could spend a while studying and it’s possible you’ll find yourself with a considerably refined listing of allowed issues, scripts, stylesheets, and so on.
In DasBlog Core (the cross platform weblog engine that runs this weblog) Mark Downie makes these configurable and makes use of the NWebSpec ASP.NET Middleware library so as to add the wanted headers.
if (SecurityStyleSources != null && SecurityScriptSources != null && DefaultSources != null)
{
app.UseCsp(choices => choices
.DefaultSources(s => s.Self()
.CustomSources(DefaultSources)
)
.StyleSources(s => s.Self()
.CustomSources(SecurityStyleSources)
.UnsafeInline()
)
.ScriptSources(s => s.Self()
.CustomSources(SecurityScriptSources)
.UnsafeInline()
.UnsafeEval()
)
);
}
Every of these variables comes out of a config file. Sure, it could be extra safety in the event that they got here out of a vault or had been even onerous coded.
DasBlog is a fairly large and funky app and we observed instantly upon Mark upgrading it to .NET 6 that we had been unable to make use of Sizzling Reload (through dotnet watch or from VS 2022). We will complain about it, or we will study the way it works and why it isn’t working for us!
Bear in mind: Nothing in your pc is hidden from you.
Beginning with a easy “View Supply” we will see a JavaScript embody on the very backside that’s positively not mine!
Ok, this makes sense as we know not only does HotReload support C# (code behinds) but also Markup via Razor Pages and changing CSS! It would definitely need to communicate "back home" to the runner which is either "dotnet watch" or VS2022. If I change the ASPNETCORE_ENVIRONMENT to "Production" (either via launch.json, launchsettings, or an environment variable like this, I can see that extra HotReload helper script isn't there:
C:githubwshotreloadtest>dotnet run --environment="Production"
Building...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:7216
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5216
Remember: You never want to use dotnet run in production! It's an SDK building command! You'll want to use dotnet exec your.dll, dotnet your.dll, or best of all, in .NET 6 just call the EXE directly! .binDebugnet6.0wshotreloadtest.exe in my example. Why? dotnet run will always assume it's in Development (you literally tell it to restore, build, and exec in one run command) if you run it. You'll note that running the actual EXE is always WAY faster as well! Don't ship your .NET SDK to your webserver and don't recompile the whole thing on startup in production!We can see that that aspnnetcore-browser-refresh.js is the client side of Development-time HotReload. Looking at our browser console we see :
Refused to connect to 'wss://localhost:62486/'That's a lot to think about. I started out my ASP.NET Web App's middle ware saying it was OK to talk "back to myself" but nowhere else.
because it violates the following Content Security Policy
directive: "default-src 'self'".
Note that 'connect-src' was not explicitly set,
so 'default-src' is used as a fallback.
app.UseCsp(options => options.DefaultSources(s => s.Self()));Hm, self seems reasonable, why can't the browser connect BACK to the dotnet run'ed Kestrel Web Server? It's all localhost, right? Well, specifically it's http://localhost not ws://localhost, or even wss://localhost (that extra s is for secure) so I need to explicitly allow ws: or wss: or both, but only in Development. Maybe like this (again, I'm using NWebSpec, but these are just HTTP Headers so you can literally just add them if you want, hardcoded.)
app.UseCsp(options => options.DefaultSources(s => s.Self())But port numbers change, right? Let's do just wss:, only in Development. Now, if I'm using both CSPs and WebSockets (ws:, wss:) in Production, I'll need to be intentional about this. What's the moral? If you start using CSP Headers to tighten things up, be conscious and aware of the headers you need for conveniences like Hot Reload in Development versus whatever things you may need in Production. Hope this helps save you some time!
.ConnectSources(s => s.CustomSources("wss://localhost:62895")));
Sponsor: At Rocket Mortgage® the work you do around here will be 100% impactful but won’t take all your free time, giving you the perfect work-life balance. Or as we call it, tech/life balance! Learn more.