diff --git a/.github/workflows/BuildAndPack.yml b/.github/workflows/BuildAndPack.yml index 8422193..ce8bf4a 100644 --- a/.github/workflows/BuildAndPack.yml +++ b/.github/workflows/BuildAndPack.yml @@ -21,7 +21,7 @@ jobs: - os: linux vm: ubuntu-latest - os: macos - vm: macos-13 # latest is arm64, and it breaks a bunch of stuff + vm: macos-14 # latest is arm64, and it breaks a bunch of stuff env: MSBuildEnableWorkloadResolver: false name: ${{ matrix.os}} diff --git a/global.json b/global.json index b5cd1b7..25b92a9 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,6 @@ { "sdk": { - "version": "10.0.100", - "rollForward": "disable", - "allowPrerelease": true + "version": "10.0.101", + "allowPrerelease": false } } \ No newline at end of file diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder.g.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder.g.cs index 9280a14..749a664 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder.g.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder.g.cs @@ -178,18 +178,6 @@ public CustomDirectiveBuilder WithHashSha512(string hash) return WithHash("sha512", hash); } - /// - /// Allow sources for content generated using the HashTagHelper. - /// - /// The CSP builder for method chaining - public CustomDirectiveBuilder WithHashTagHelper() - { - SourceBuilders.Add( - ctx => string.Join(" ", ctx.GetScriptCSPHashes()), - $"NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder.{nameof(WithHashTagHelper)}"); - return this; - } - /// /// Allows the use of inline resources, such as inline <scripT> elements, javascript : URLs, /// inline event handlers, and inline <style> elements diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder.g.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder.g.cs index c2fc38b..aed455b 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder.g.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder.g.cs @@ -178,18 +178,6 @@ public DefaultSourceDirectiveBuilder WithHashSha512(string hash) return WithHash("sha512", hash); } - /// - /// Allow sources for content generated using the HashTagHelper. - /// - /// The CSP builder for method chaining - public DefaultSourceDirectiveBuilder WithHashTagHelper() - { - SourceBuilders.Add( - ctx => string.Join(" ", ctx.GetScriptCSPHashes()), - $"NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder.{nameof(WithHashTagHelper)}"); - return this; - } - /// /// Allows the use of inline resources, such as inline <scripT> elements, javascript : URLs, /// inline event handlers, and inline <style> elements diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceAttrDirectiveBuilder.g.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceAttrDirectiveBuilder.g.cs index 1365ff8..a7e6a51 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceAttrDirectiveBuilder.g.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceAttrDirectiveBuilder.g.cs @@ -77,7 +77,7 @@ public StyleSourceAttrDirectiveBuilder WithHashSha512(string hash) public StyleSourceAttrDirectiveBuilder WithHashTagHelper() { SourceBuilders.Add( - ctx => string.Join(" ", ctx.GetScriptCSPHashes()), + ctx => string.Join(" ", ctx.GetStyleCSPHashes()), $"NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceAttrDirectiveBuilder.{nameof(WithHashTagHelper)}"); return this; } diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceDirectiveBuilder.g.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceDirectiveBuilder.g.cs index 189a40a..f688099 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceDirectiveBuilder.g.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceDirectiveBuilder.g.cs @@ -185,7 +185,7 @@ public StyleSourceDirectiveBuilder WithHashSha512(string hash) public StyleSourceDirectiveBuilder WithHashTagHelper() { SourceBuilders.Add( - ctx => string.Join(" ", ctx.GetScriptCSPHashes()), + ctx => string.Join(" ", ctx.GetStyleCSPHashes()), $"NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceDirectiveBuilder.{nameof(WithHashTagHelper)}"); return this; } diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceElemDirectiveBuilder.g.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceElemDirectiveBuilder.g.cs index 6dcdc78..36fb2fa 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceElemDirectiveBuilder.g.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Generated/netcoreapp3.1/SourceGenerator/SourceGenerator.ContentSecurityPolicyGenerator/NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceElemDirectiveBuilder.g.cs @@ -185,7 +185,7 @@ public StyleSourceElemDirectiveBuilder WithHashSha512(string hash) public StyleSourceElemDirectiveBuilder WithHashTagHelper() { SourceBuilders.Add( - ctx => string.Join(" ", ctx.GetScriptCSPHashes()), + ctx => string.Join(" ", ctx.GetStyleCSPHashes()), $"NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.StyleSourceElemDirectiveBuilder.{nameof(WithHashTagHelper)}"); return this; } diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/GeneratorHelpers/MixinTypes.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/GeneratorHelpers/MixinTypes.cs index dfc39d0..3c997a9 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/GeneratorHelpers/MixinTypes.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/GeneratorHelpers/MixinTypes.cs @@ -74,7 +74,17 @@ internal enum MixinTypes None = 1 << 12, /// - /// Convenience combination of all mixin flags. + /// Adds the 'WithHashTagHelper' source, by calling GetScriptCSPHashes + /// + ScriptHashTagHelper = 1 << 13, + + /// + /// Adds the 'WithHashTagHelper' source, by calling GetStyleCSPHashes + /// + StyleHashTagHelper = 1 << 14, + + /// + /// Convenience combination of all mixin flags except and /// All = Self | HostSource | diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceAttrDirectiveBuilder.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceAttrDirectiveBuilder.cs index 6986cdf..6e24f44 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceAttrDirectiveBuilder.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceAttrDirectiveBuilder.cs @@ -9,7 +9,7 @@ namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy; /// can be specified for all JavaScript script sources using script-src, or just for /// <script> elements using script-src-elem.) /// -[CspMixin(MixinTypes.UnsafeHashes | MixinTypes.Hash | MixinTypes.UnsafeInline | MixinTypes.None | MixinTypes.ReportSample)] +[CspMixin(MixinTypes.UnsafeHashes | MixinTypes.Hash | MixinTypes.UnsafeInline | MixinTypes.None | MixinTypes.ReportSample | MixinTypes.ScriptHashTagHelper)] public partial class ScriptSourceAttrDirectiveBuilder : CspDirectiveBuilder { /// diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceDirectiveBuilder.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceDirectiveBuilder.cs index 8aa181a..d38546b 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceDirectiveBuilder.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceDirectiveBuilder.cs @@ -5,7 +5,7 @@ /// This includes not only URLs loaded directly into <script> elements, but also things /// like inline script event handlers (onclick) and XSLT stylesheets which can trigger script execution. /// -[CspMixin(MixinTypes.All)] +[CspMixin(MixinTypes.All | MixinTypes.ScriptHashTagHelper)] public partial class ScriptSourceDirectiveBuilder : CspDirectiveBuilder { /// diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceElemDirectiveBuilder.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceElemDirectiveBuilder.cs index 661f75c..461e613 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceElemDirectiveBuilder.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/ScriptSourceElemDirectiveBuilder.cs @@ -9,7 +9,7 @@ namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy; /// "unsafe-eval" check, and XSLT stylesheets. (Valid sources can be specified for all /// JavaScript script sources using script-src, or just for inline script handlers using script-src-attr.) /// -[CspMixin(MixinTypes.All & ~MixinTypes.UnsafeHashes)] // Everything except unsafe hashes +[CspMixin((MixinTypes.All & ~MixinTypes.UnsafeHashes) | MixinTypes.ScriptHashTagHelper)] // Everything except unsafe hashes public partial class ScriptSourceElemDirectiveBuilder : CspDirectiveBuilder { /// diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceAttrDirectiveBuilder.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceAttrDirectiveBuilder.cs index ecdce43..d0f6984 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceAttrDirectiveBuilder.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceAttrDirectiveBuilder.cs @@ -6,7 +6,7 @@ namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy; /// The directive does not set valid sources for <style> elements and <link> elements with rel="stylesheet". /// These are set using style-src-elem (and valid sources for all styles may be set with style-src). /// -[CspMixin(MixinTypes.UnsafeInline | MixinTypes.UnsafeHashes | MixinTypes.Hash | MixinTypes.ReportSample | MixinTypes.None)] +[CspMixin(MixinTypes.UnsafeInline | MixinTypes.UnsafeHashes | MixinTypes.Hash | MixinTypes.ReportSample | MixinTypes.None | MixinTypes.StyleHashTagHelper)] public partial class StyleSourceAttrDirectiveBuilder : CspDirectiveBuilder { /// diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceDirectiveBuilder.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceDirectiveBuilder.cs index 72a0c43..db1b430 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceDirectiveBuilder.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceDirectiveBuilder.cs @@ -4,7 +4,7 @@ /// The style-src directive specifies valid sources for sources for stylesheets. /// [CspMixin(MixinTypes.HostSource | MixinTypes.SchemeSource | MixinTypes.Self | MixinTypes.None | MixinTypes.UnsafeEval - | MixinTypes.UnsafeInline | MixinTypes.UnsafeHashes | MixinTypes.Hash | MixinTypes.Nonce | MixinTypes.ReportSample)] + | MixinTypes.UnsafeInline | MixinTypes.UnsafeHashes | MixinTypes.Hash | MixinTypes.Nonce | MixinTypes.ReportSample | MixinTypes.StyleHashTagHelper)] public partial class StyleSourceDirectiveBuilder : CspDirectiveBuilder { /// diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceElemDirectiveBuilder.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceElemDirectiveBuilder.cs index 3253d8a..4cd500e 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceElemDirectiveBuilder.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/Headers/ContentSecurityPolicy/StyleSourceElemDirectiveBuilder.cs @@ -8,7 +8,7 @@ namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy; /// set using style-src-attr (and valid sources for all styles may be set with style-src). /// [CspMixin(MixinTypes.HostSource | MixinTypes.SchemeSource | MixinTypes.Self | MixinTypes.None | MixinTypes.UnsafeEval - | MixinTypes.UnsafeInline | MixinTypes.Hash | MixinTypes.Nonce | MixinTypes.ReportSample)] + | MixinTypes.UnsafeInline | MixinTypes.Hash | MixinTypes.Nonce | MixinTypes.ReportSample | MixinTypes.StyleHashTagHelper)] public partial class StyleSourceElemDirectiveBuilder : CspDirectiveBuilder { /// diff --git a/src/SourceGenerator/SourceGenerationHelper.cs b/src/SourceGenerator/SourceGenerationHelper.cs index 099821b..dc1d21c 100644 --- a/src/SourceGenerator/SourceGenerationHelper.cs +++ b/src/SourceGenerator/SourceGenerationHelper.cs @@ -221,7 +221,14 @@ public partial class {{toGenerate.ClassName}} { return WithHash("sha512", hash); } - + """); + } + + if (Contains(mixins, MixinTypes.ScriptHashTagHelper)) + { + sb.AppendLine( + $$""" + /// /// Allow sources for content generated using the HashTagHelper. /// @@ -236,6 +243,25 @@ public partial class {{toGenerate.ClassName}} """); } + if (Contains(mixins, MixinTypes.StyleHashTagHelper)) + { + sb.AppendLine( + $$""" + + /// + /// Allow sources for content generated using the HashTagHelper. + /// + /// The CSP builder for method chaining + public {{toGenerate.ClassName}} WithHashTagHelper() + { + SourceBuilders.Add( + ctx => string.Join(" ", ctx.GetStyleCSPHashes()), + $"{{toGenerate.NameSpace}}.{{toGenerate.ClassName}}.{nameof(WithHashTagHelper)}"); + return this; + } + """); + } + if (Contains(mixins, MixinTypes.UnsafeInline)) { sb.AppendLine( diff --git a/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt b/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt index ab66974..6c96b98 100644 --- a/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt +++ b/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt @@ -381,7 +381,6 @@ namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder WithHash256(string hash) { } public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder WithHashSha384(string hash) { } public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder WithHashSha512(string hash) { } - public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder WithHashTagHelper() { } public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CustomDirectiveBuilder WithNonce() { } } public class DefaultSourceDirectiveBuilder : NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CspDirectiveBuilder @@ -408,7 +407,6 @@ namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder WithHash256(string hash) { } public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder WithHashSha384(string hash) { } public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder WithHashSha512(string hash) { } - public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder WithHashTagHelper() { } public NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.DefaultSourceDirectiveBuilder WithNonce() { } } public class FontSourceDirectiveBuilder : NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy.CspDirectiveBuilder diff --git a/test/SourceGenerator.Test/ContentSecurityPolicyGeneratorTests.cs b/test/SourceGenerator.Test/ContentSecurityPolicyGeneratorTests.cs index 549a0d9..d9eaf8f 100644 --- a/test/SourceGenerator.Test/ContentSecurityPolicyGeneratorTests.cs +++ b/test/SourceGenerator.Test/ContentSecurityPolicyGeneratorTests.cs @@ -30,7 +30,7 @@ public Task CanGenerateCspMixinsInGlobalNamespace() namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy { - [CspMixin(MixinTypes.All)] + [CspMixin(MixinTypes.All | MixinTypes.ScriptHashTagHelper)] public partial class TestBuilder : CspDirectiveBuilder { }