-
Notifications
You must be signed in to change notification settings - Fork 87
Description
Our team maintains a Razor Component Library for our web template which allows us to share a common look and feel, dependencies, etc. We also include some common extension methods to help with configuring applications. I'd like to add this library to that template and include some useful extension methods to make it easier to configure custom policies, specifically the Content-Security-Policy. I just don't see a good way to add items to an existing CspBuilder directive since it wipes out the previous policy. Without the ability to grab existing policies and add onto them, we're pretty much stuck with documenting it and having each developer do it themselves, and if anything changes each web application would need to be updated.
This is not a duplicate of #250 since it was dealing with the AddSecurityHeaderPolicies method specifically. I didn't see any code in there that would fix my issue here.
Some examples of extension methods would be:
EnableTemplate()to add our template-specific requirements likeImageSrc().Self().Data().EnableBrowserLink()to add theconnect-srcitems for Visual Studio's Browser Link feature when debugging.EnableGoogleAnalytics()to track the defaults for using Google Tag Manager which can be a bit hairy.
Another reason we'd like this is to allow us to use Google Analytics with a nonce. Right now we have to use unsafe-inline, use custom hashes which need maintained, or use our own middleware which would be redundant with this.
There are several ways I could work around it, but the most likely method is reflection; other options seem even worse. Just documenting it is also an option, but not only do we have issues trying to get some developers to read documentation, it's easy to miss a project when they all use their own custom code to do the same thing. Other ideas like our own custom builder would require cloning about half the project into ours which would seem to me to defeat the purpose.
I'm more than willing to work on a PR if you have a suggestion on how you'd like it integrated; I'm assuming you wouldn't want me to change the behavior of the AddDirective methods. The easiest alternative I can think of would be to add a bool useExisting = false parameter to all the directive methods. All the other options include duplicating a bunch of methods.
Other options would be a bit more invasive. Right now the AddDirective<T> method is private, so adding a public AddOrGetDirective<T> or TryGetExisting<TDirective> method seems questionable. You could potentially add a public Merge method that would allow you to merge it with another CspBuilder, but that still only helps to a point since there's no way to get the existing CspBuilder out of the ContentSecurityPolicyHeader either.
One way or another I also just want to give you huge thanks for the library. Even if I do end up just documenting things, your library will make it easier for my developers than just pointing them at MDN. I'm glad I ran across an NDC talk the plugged it; I'd somehow missed it on your blog, and my searches were focused specifically on the Content-Security-Policy which didn't seem to include it, at least near the top.