Browse Source

Refactoring

pull/16496/head
Salih 3 years ago
parent
commit
f47c721382
  1. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/NonceScriptTagHelper.cs
  2. 4
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeaderNonceHelper.cs
  3. 24
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs
  4. 11
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersOptions.cs

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/AbpNonceScriptTagHelper.cs → framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/TagHelpers/NonceScriptTagHelper.cs

@ -6,7 +6,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers;
[HtmlTargetElement("script")]
public class AbpNonceScriptTagHelper : AbpTagHelper
public class NonceScriptTagHelper : AbpTagHelper
{
[HtmlAttributeNotBound]
[ViewContext]

4
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeaderNonceHelper.cs

@ -15,9 +15,9 @@ public static class AbpSecurityHeaderNonceHelper
return string.Empty;
}
public static string GetScriptNonceAttribute(this IHtmlHelper htmlHelper)
public static IHtmlContent GetScriptNonceAttribute(this IHtmlHelper htmlHelper)
{
var nonce = htmlHelper.GetScriptNonce();
return string.IsNullOrEmpty(nonce) ? string.Empty : $"nonce=\"{nonce}\"";
return nonce == string.Empty ? HtmlString.Empty : new HtmlString($"nonce=\"{nonce}\"");
}
}

24
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersMiddleware.cs

@ -34,8 +34,13 @@ public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
var requestAcceptTypeHtml = context.Request.Headers["Accept"].Any(x =>
x.Contains("text/html") || x.Contains("*/*") || x.Contains("application/xhtml+xml"));
if (!requestAcceptTypeHtml || !Options.Value.UseContentSecurityPolicyHeader || await AlwaysIgnoreContentTypes(context) || context.GetEndpoint() == null)
if (!requestAcceptTypeHtml
|| !Options.Value.UseContentSecurityPolicyHeader
|| await AlwaysIgnoreContentTypes(context)
|| context.GetEndpoint() == null
|| Options.Value.IgnoredNonceScriptPaths.Any(x => context.Request.Path.StartsWithSegments(x.EnsureStartsWith('/'))))
{
AddOtherHeaders(context);
await next.Invoke(context);
return;
}
@ -68,17 +73,16 @@ public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
AddHeader(context, "Content-Security-Policy", BuildContentSecurityPolicyValue(context));
AddOtherHeaders(context);
return Task.CompletedTask;
});
AddOtherHeaders(context);
await next.Invoke(context);
}
private async Task<bool> AlwaysIgnoreContentTypes(HttpContext context)
{
foreach (var selector in Options.Value.AlwaysIgnoreSecurityHeadersSelectors)
foreach (var selector in Options.Value.IgnoredNonceScriptSelectors)
{
if(await selector(context))
{
@ -103,26 +107,26 @@ public class AbpSecurityHeadersMiddleware : IMiddleware, ITransientDependency
context.Items.TryGetValue(AbpAspNetCoreConsts.ScriptNonceKey, out var nonce) &&
nonce is string nonceValue && !string.IsNullOrEmpty(nonceValue)))
{
return ContentSecurityPolicyValueDictionaryToCSPString();
return ContentSecurityPolicyValuesToCSPString();
}
var scriptSrcValue = "";
if (Options.Value.ContentSecurityPolicyValueDictionary.TryGetValue(ScriptSrcKey, out var scriptSrc))
if (Options.Value.ContentSecurityPolicyValues.TryGetValue(ScriptSrcKey, out var scriptSrc))
{
scriptSrcValue = string.Join(" ", scriptSrc);
}
scriptSrcValue += $" 'nonce-{nonceValue}'";
return ContentSecurityPolicyValueDictionaryToCSPString(true) + $"; {ScriptSrcKey} {scriptSrcValue}";
return ContentSecurityPolicyValuesToCSPString(true) + $"; {ScriptSrcKey} {scriptSrcValue}";
}
protected virtual string ContentSecurityPolicyValueDictionaryToCSPString(bool ignoreScriptSrc = false)
protected virtual string ContentSecurityPolicyValuesToCSPString(bool ignoreScriptSrc = false)
{
if (Options.Value.ContentSecurityPolicyValueDictionary.Any())
if (Options.Value.ContentSecurityPolicyValues.Any())
{
return string.Join("; ",
Options.Value.ContentSecurityPolicyValueDictionary.WhereIf(ignoreScriptSrc, x => x.Key != ScriptSrcKey)
Options.Value.ContentSecurityPolicyValues.WhereIf(ignoreScriptSrc, x => x.Key != ScriptSrcKey)
.Select(x => $"{x.Key} {string.Join(" ", x.Value)}"));
}

11
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/AbpSecurityHeadersOptions.cs

@ -11,16 +11,19 @@ public class AbpSecurityHeadersOptions
public bool UseContentSecurityPolicyNonce { get; set; }
public Dictionary<string,IEnumerable<string>> ContentSecurityPolicyValueDictionary { get; }
public Dictionary<string,IEnumerable<string>> ContentSecurityPolicyValues { get; }
public Dictionary<string, string> Headers { get; }
public List<Func<HttpContext, Task<bool>>> AlwaysIgnoreSecurityHeadersSelectors { get; }
public List<Func<HttpContext, Task<bool>>> IgnoredNonceScriptSelectors { get; }
public IEnumerable<string> IgnoredNonceScriptPaths { get; }
public AbpSecurityHeadersOptions()
{
Headers = new Dictionary<string, string>();
ContentSecurityPolicyValueDictionary = new Dictionary<string, IEnumerable<string>>();
AlwaysIgnoreSecurityHeadersSelectors = new List<Func<HttpContext, Task<bool>>>();
ContentSecurityPolicyValues = new Dictionary<string, IEnumerable<string>>();
IgnoredNonceScriptSelectors = new List<Func<HttpContext, Task<bool>>>();
IgnoredNonceScriptPaths = new List<string>();
}
}

Loading…
Cancel
Save