Skip to content

Commit

Permalink
feature/frozen-dictionary (#155)
Browse files Browse the repository at this point in the history
* Middleware now uses a FrozenDictionary rather than a Dictionary, improving speed of execution after first time through the Invoke method.
Also removed an unnecessary string.

* Ran dotnet-format on codebase

* Patch version bump

* Increased description of project a little
  • Loading branch information
jamie-taylor-rjj authored Dec 27, 2024
1 parent 54fc9a1 commit b1cf862
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
4 changes: 2 additions & 2 deletions src/OwaspHeaders.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

<!-- NuGet metadata -->
<PackageId>OwaspHeaders.Core</PackageId>
<Version>9.6.1</Version>
<Version>9.6.2</Version>
<Authors>Jamie Taylor</Authors>
<Company>RJJ Software Ltd</Company>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Copyright (c) Jamie Taylor / RJJ Software Ltd</Copyright>
<PackageTags>owasp http headers security</PackageTags>
<Description>An ASP.NET Core Middleware which adds the OWASP recommended HTTP headers for enhanced security.</Description>
<Description>An ASP.NET Core Middleware which adds the OWASP recommended HTTP headers, with a single line of code, for enhanced security.</Description>
<PackageIcon>icon.png</PackageIcon>
<PackageReadmeFile>README-NuGet.md</PackageReadmeFile>
<PackageProjectUrl>https://gaprogman.github.io/OwaspHeaders.Core/</PackageProjectUrl>
Expand Down
55 changes: 24 additions & 31 deletions src/SecureHeadersMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Frozen;
using System.Linq;
using System.Threading.Tasks;

namespace OwaspHeaders.Core;
Expand All @@ -9,16 +10,15 @@ namespace OwaspHeaders.Core;
/// </summary>
public class SecureHeadersMiddleware
{
private string _calculatedContentSecurityPolicy;
private readonly Dictionary<string, string> _headers;
private FrozenDictionary<string, string> _headers;
private readonly RequestDelegate _next;
private readonly SecureHeadersMiddlewareConfiguration _config;

public SecureHeadersMiddleware(RequestDelegate next, SecureHeadersMiddlewareConfiguration config)
{
_config = config;
_next = next;
_headers = new Dictionary<string, string>();
_headers = FrozenDictionary<string, string>.Empty;
}

/// <summary>
Expand All @@ -39,7 +39,7 @@ public async Task InvokeAsync(HttpContext httpContext)
{
if (_headers.Count == 0)
{
GenerateRelevantHeaders();
_headers = GenerateRelevantHeaders();
}

foreach (var (key, value) in _headers)
Expand All @@ -52,88 +52,81 @@ public async Task InvokeAsync(HttpContext httpContext)
await _next(httpContext);
}

private void GenerateRelevantHeaders()
private FrozenDictionary<string, string> GenerateRelevantHeaders()
{
var temporaryDictionary = new Dictionary<string, string>();

if (_config.UseHsts)
{
_headers.TryAdd(Constants.StrictTransportSecurityHeaderName,
temporaryDictionary.Add(Constants.StrictTransportSecurityHeaderName,
_config.HstsConfiguration.BuildHeaderValue());
}

if (_config.UseXFrameOptions)
{
_headers.TryAdd(Constants.XFrameOptionsHeaderName,
temporaryDictionary.Add(Constants.XFrameOptionsHeaderName,
_config.XFrameOptionsConfiguration.BuildHeaderValue());
}

if (_config.UseXssProtection)
{
_headers.TryAdd(Constants.XssProtectionHeaderName,
temporaryDictionary.Add(Constants.XssProtectionHeaderName,
_config.XssConfiguration.BuildHeaderValue());
}

if (_config.UseXContentTypeOptions)
{
_headers.TryAdd(Constants.XContentTypeOptionsHeaderName, Constants.XContentTypeOptionsValue);
temporaryDictionary.Add(Constants.XContentTypeOptionsHeaderName, Constants.XContentTypeOptionsValue);
}

if (_config.UseContentSecurityPolicyReportOnly)
{
if (string.IsNullOrWhiteSpace(_calculatedContentSecurityPolicy))
{
_calculatedContentSecurityPolicy =
_config.ContentSecurityPolicyReportOnlyConfiguration.BuildHeaderValue();
}

_headers.TryAdd(Constants.ContentSecurityPolicyReportOnlyHeaderName,
_calculatedContentSecurityPolicy);
temporaryDictionary.Add(Constants.ContentSecurityPolicyReportOnlyHeaderName,
_config.ContentSecurityPolicyReportOnlyConfiguration.BuildHeaderValue());
}
else if (_config.UseContentSecurityPolicy)
{
if (string.IsNullOrWhiteSpace(_calculatedContentSecurityPolicy))
{
_calculatedContentSecurityPolicy = _config.ContentSecurityPolicyConfiguration.BuildHeaderValue();
}

_headers.TryAdd(Constants.ContentSecurityPolicyHeaderName,
_calculatedContentSecurityPolicy);
temporaryDictionary.Add(Constants.ContentSecurityPolicyHeaderName,
_config.ContentSecurityPolicyConfiguration.BuildHeaderValue());
}

if (_config.UseXContentSecurityPolicy)
{
_headers.TryAdd(Constants.XContentSecurityPolicyHeaderName,
temporaryDictionary.Add(Constants.XContentSecurityPolicyHeaderName,
_config.ContentSecurityPolicyConfiguration.BuildHeaderValue());
}

if (_config.UsePermittedCrossDomainPolicy)
{
_headers.TryAdd(Constants.PermittedCrossDomainPoliciesHeaderName,
temporaryDictionary.Add(Constants.PermittedCrossDomainPoliciesHeaderName,
_config.PermittedCrossDomainPolicyConfiguration.BuildHeaderValue());
}

if (_config.UseReferrerPolicy)
{
_headers.TryAdd(Constants.ReferrerPolicyHeaderName,
temporaryDictionary.Add(Constants.ReferrerPolicyHeaderName,
_config.ReferrerPolicy.BuildHeaderValue());
}

if (_config.UseExpectCt)
{
_headers.TryAdd(Constants.ExpectCtHeaderName,
temporaryDictionary.Add(Constants.ExpectCtHeaderName,
_config.ExpectCt.BuildHeaderValue());
}

if (_config.UseCacheControl)
{
_headers.TryAdd(Constants.CacheControlHeaderName,
temporaryDictionary.Add(Constants.CacheControlHeaderName,
_config.CacheControl.BuildHeaderValue());
}

if (_config.UseCrossOriginResourcePolicy)
{
_headers.TryAdd(Constants.CrossOriginResourcePolicyHeaderName,
temporaryDictionary.Add(Constants.CrossOriginResourcePolicyHeaderName,
_config.CrossOriginResourcePolicy.BuildHeaderValue());
}

return temporaryDictionary.ToFrozenDictionary();
}

private bool RequestShouldBeIgnored(PathString requestedPath)
Expand Down

0 comments on commit b1cf862

Please sign in to comment.