Skip to content

Commit

Permalink
Merge pull request #93 from GaProgMan/feature/88-remove-support-for-n…
Browse files Browse the repository at this point in the history
…et-framework

Removed support for .NET Framework-based ASP .NET Core applications
  • Loading branch information
GaProgMan authored Dec 3, 2023
2 parents 71fde75 + 66dca1d commit 25bbbf3
Show file tree
Hide file tree
Showing 35 changed files with 1,048 additions and 864 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc;

namespace example.Controllers;
namespace OwaspHeaders.Core.Example.Controllers;

[ApiController]
[Route("/")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using OwaspHeaders.Core.Extensions;
using OwaspHeaders.Core.Models;

namespace example.Helpers;
namespace OwaspHeaders.Core.Example.Helpers;

/// <summary>
/// This class is useful for testing the Secure Headers middleware with a set of realistic
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using OwaspHeaders.Core;
using OwaspHeaders.Core.Extensions;
using Xunit;

namespace OwaspHeaders.Core.Tests.CustomHeaders
{
public class CacheControlHeaderOptionsTests
{
private int _onNextCalledTimes;
private readonly Task _onNextResult = Task.FromResult(0);
private readonly RequestDelegate _onNext;
private readonly DefaultHttpContext _context;

public CacheControlHeaderOptionsTests()
{
_onNext = _ =>
{
Interlocked.Increment(ref _onNextCalledTimes);
return _onNextResult;
};
_context = new DefaultHttpContext();
}

[Fact]
public async Task Invoke_CacheControl_IsPrivate_HeaderIsPresent()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseCacheControl(@private: true).Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseCacheControl);
Assert.True(_context.Response.Headers.ContainsKey(Constants.CacheControlHeaderName));

_context.Response.Headers.TryGetValue(Constants.CacheControlHeaderName, out var headerValues);
Assert.True(headerValues.Any());
Assert.Contains("private", headerValues.First());
Assert.DoesNotContain("no-cache", headerValues.First());
Assert.DoesNotContain("no-store", headerValues.First());
}

[Fact]
public async Task Invoke_CacheControl_MustRevalidate_HeaderIsPresent()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseCacheControl(mustRevalidate: true).Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseCacheControl);
Assert.True(_context.Response.Headers.ContainsKey(Constants.CacheControlHeaderName));

_context.Response.Headers.TryGetValue(Constants.CacheControlHeaderName, out var headerValues);
Assert.True(headerValues.Any());
Assert.Contains("must-revalidate", headerValues.First());
Assert.DoesNotContain("no-cache", headerValues.First());
Assert.DoesNotContain("no-store", headerValues.First());
}

[Fact]
public async Task Invoke_CacheControl_NoCache_HeaderIsPresent()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseCacheControl(noCache: true).Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseCacheControl);
Assert.True(_context.Response.Headers.ContainsKey(Constants.CacheControlHeaderName));

_context.Response.Headers.TryGetValue(Constants.CacheControlHeaderName, out var headerValues);
Assert.True(headerValues.Any());
Assert.Contains("no-cache", headerValues.First());
Assert.DoesNotContain("private", headerValues.First());
Assert.DoesNotContain("must-revalidate", headerValues.First());
}

[Fact]
public async Task Invoke_CacheControl_NoStore_HeaderIsPresent()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseCacheControl(noStore: true).Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseCacheControl);
Assert.True(_context.Response.Headers.ContainsKey(Constants.CacheControlHeaderName));

_context.Response.Headers.TryGetValue(Constants.CacheControlHeaderName, out var headerValues);
Assert.True(headerValues.Any());
Assert.Contains("no-store", headerValues.First());
Assert.DoesNotContain("private", headerValues.First());
Assert.DoesNotContain("must-revalidate", headerValues.First());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
using System.Threading.Tasks;
using OwaspHeaders.Core;
using OwaspHeaders.Core.Enums;
using OwaspHeaders.Core.Extensions;
using Xunit;

namespace OwaspHeaders.Core.Tests.CustomHeaders
{
public class ContentSecurityPolicyOptionsTests : SecureHeadersTests
{
[Fact]
public async Task When_UseContentDefaultSecurityPolicyCalled_Header_Is_Present()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseContentDefaultSecurityPolicy().Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
if (headerPresentConfig.UseContentSecurityPolicy)
{
Assert.True(_context.Response.Headers.ContainsKey(Constants.ContentSecurityPolicyHeaderName));
Assert.Equal("script-src 'self';object-src 'self';block-all-mixed-content;upgrade-insecure-requests;",
_context.Response.Headers[Constants.ContentSecurityPolicyHeaderName]);
}
else
{
Assert.False(_context.Response.Headers.ContainsKey(Constants.ContentSecurityPolicyHeaderName));
}
}

[Fact]
public async Task When_UseContentDefaultSecurityPolicyNotCalled_Header_Not_Present()
{
// arrange
var headerNotPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerNotPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.False(headerNotPresentConfig.UseContentSecurityPolicy);
Assert.False(_context.Response.Headers.ContainsKey(Constants.ContentSecurityPolicyHeaderName));
}

[Fact]
public async Task Invoke_ContentSecurityPolicyHeaderName_HeaderIsPresent_WithMultipleCspSandboxTypes()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseContentSecurityPolicy().Build();
headerPresentConfig.SetCspSandBox(CspSandboxType.allowForms, CspSandboxType.allowScripts,
CspSandboxType.allowSameOrigin);
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(_context.Response.Headers.ContainsKey(Constants.ContentSecurityPolicyHeaderName));
Assert.Equal(
"sandbox allow-forms allow-scripts allow-same-origin;block-all-mixed-content;upgrade-insecure-requests;",
_context.Response.Headers[Constants.ContentSecurityPolicyHeaderName]);
}

[Fact]
public async Task Invoke_ContentSecurityPolicyReportOnly_HeaderIsPresent_WithMultipleCspSandboxTypes()
{
const string reportUri = "https://localhost:5001/report-uri";
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseContentSecurityPolicyReportOnly(reportUri).Build();
headerPresentConfig.SetCspSandBox(CspSandboxType.allowForms, CspSandboxType.allowScripts,
CspSandboxType.allowSameOrigin);
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(_context.Response.Headers.ContainsKey(Constants.ContentSecurityPolicyReportOnlyHeaderName));
Assert.Equal($"block-all-mixed-content;upgrade-insecure-requests;report-uri {reportUri};",
_context.Response.Headers[Constants.ContentSecurityPolicyReportOnlyHeaderName]);
}

[Fact]
public async Task Invoke_ContentSecurityPolicyReportOnly_HeaderIsNotPresent()
{
// arrange
var headerNotPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerNotPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.False(headerNotPresentConfig.UseContentSecurityPolicyReportOnly);
Assert.False(_context.Response.Headers.ContainsKey(Constants.ContentSecurityPolicyReportOnlyHeaderName));
}

[Fact]
public async Task Invoke_XContentSecurityPolicyHeaderName_HeaderIsPresent()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseContentSecurityPolicy(useXContentSecurityPolicy: true).Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseXContentSecurityPolicy);
Assert.True(_context.Response.Headers.ContainsKey(Constants.XContentSecurityPolicyHeaderName));
Assert.Equal("block-all-mixed-content;upgrade-insecure-requests;",
_context.Response.Headers[Constants.XContentSecurityPolicyHeaderName]);

}

[Fact]
public async Task Invoke_XContentSecurityPolicyHeaderName_HeaderIsNotPresent()
{
// arrange
var headerNotPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerNotPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.False(headerNotPresentConfig.UseXContentSecurityPolicy);
Assert.False(_context.Response.Headers.ContainsKey(Constants.XContentSecurityPolicyHeaderName));
}
}
}
46 changes: 46 additions & 0 deletions OwaspHeaders.Core.Tests/CustomHeaders/CrossOriginOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Threading.Tasks;
using OwaspHeaders.Core;
using OwaspHeaders.Core.Extensions;
using OwaspHeaders.Core.Models;
using Xunit;

namespace OwaspHeaders.Core.Tests.CustomHeaders
{
public class CrossOriginOptionsTests : SecureHeadersTests
{
[Fact]
public async Task When_UseCrossOriginResourcePolicyCalled_Header_Is_Present()
{
// arrange
var headerPresentConfig =
SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseCrossOriginResourcePolicy().Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseCrossOriginResourcePolicy);
Assert.True(_context.Response.Headers.ContainsKey(Constants.CrossOriginResourcePolicyHeaderName));
Assert.Equal(CrossOriginResourcePolicy.SameOriginValue,
_context.Response.Headers[Constants.CrossOriginResourcePolicyHeaderName]);
}

[Fact]
public async Task When_UseCrossOriginResourcePolicyNotCalled_Header_Not_Present()
{
// arrange
var headerNotPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerNotPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.False(headerNotPresentConfig.UseCrossOriginResourcePolicy);
Assert.False(_context.Response.Headers.ContainsKey(Constants.CrossOriginResourcePolicyHeaderName));
}
}
}
62 changes: 62 additions & 0 deletions OwaspHeaders.Core.Tests/CustomHeaders/ExpectCtOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Threading.Tasks;
using OwaspHeaders.Core;
using OwaspHeaders.Core.Extensions;
using Xunit;

namespace OwaspHeaders.Core.Tests.CustomHeaders
{
public class ExpectCtOptionsTests : SecureHeadersTests
{
[Fact]
public async Task When_UseExpectCtCalled_Header_Is_Present()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseExpectCt("https://test.com/report").Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseExpectCt);
Assert.True(_context.Response.Headers.ContainsKey(Constants.ExpectCtHeaderName));
Assert.Equal(headerPresentConfig.ExpectCt.BuildHeaderValue(),
_context.Response.Headers[Constants.ExpectCtHeaderName]);
}

[Fact]
public async Task When_UseExpectCtNotCalled_Header_Not_Present()
{
// arrange
var headerNotPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerNotPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.False(headerNotPresentConfig.UseExpectCt);
Assert.False(_context.Response.Headers.ContainsKey(Constants.ExpectCtHeaderName));
}

[Fact]
public async Task When_UseExpectCtCalled_HeaderIsPresent_ReportUri_Optional()
{
// arrange
var headerPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
.UseExpectCt(string.Empty).Build();
var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);

// act
await secureHeadersMiddleware.InvokeAsync(_context);

// assert
Assert.True(headerPresentConfig.UseExpectCt);
Assert.True(_context.Response.Headers.ContainsKey(Constants.ExpectCtHeaderName));
Assert.Equal(headerPresentConfig.ExpectCt.BuildHeaderValue(),
_context.Response.Headers[Constants.ExpectCtHeaderName]);
}
}
}
Loading

0 comments on commit 25bbbf3

Please sign in to comment.