Skip to content

Commit

Permalink
Merge pull request #86 from miguelcrpinto/feature/issue-76-Cross-Orig…
Browse files Browse the repository at this point in the history
…in-Resource-Policy_not_supported

Implemented Cross-Origin-Resource-Policy response header
  • Loading branch information
GaProgMan authored Jun 5, 2023
2 parents 19474cc + ddc58ca commit 433cbb7
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 2 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ This changelog represents all of the major (i.e. breaking) changes made to the O
| 2 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class <br /> also uses .NET Core 2.0 |
| 1 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class <br /> also uses .NET Standard 1.4 |

### Version 7

This version adds the Cross-Origin-Resource-Policy header with the OWASP recommended value "same-origin" to the list of default headers in the `BuildDefaultConfiguration()` extension method. This was requested via [issue #76](https://github.com/GaProgMan/OwaspHeaders.Core/issues/76).

### Version 6

This version removes Expect-CT Header from the list of default headers in the `BuildDefaultConfiguration()` extension method. This is related to [issue #72](https://github.com/GaProgMan/OwaspHeaders.Core/issues/72).
Expand Down
2 changes: 2 additions & 0 deletions src/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ public static class Constants
public static readonly string PoweredByHeaderName = "X-Powered-By";

public static readonly string ServerHeaderName = "Server";

public static readonly string CrossOriginResourcePolicyHeaderName = "Cross-Origin-Resource-Policy";
}
}
17 changes: 17 additions & 0 deletions src/Extensions/SecureHeadersMiddlewareBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using OwaspHeaders.Core.Enums;
using OwaspHeaders.Core.Helpers;
using OwaspHeaders.Core.Models;
using static OwaspHeaders.Core.Models.CrossOriginResourcePolicy;

namespace OwaspHeaders.Core.Extensions
{
Expand Down Expand Up @@ -319,7 +320,23 @@ public static SecureHeadersMiddlewareConfiguration RemovePoweredByHeader
(this SecureHeadersMiddlewareConfiguration config)
{
config.RemoveXPoweredByHeader = true;
return config;
}

/// <summary>
/// The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the browser
/// blocks no-cors cross-origin/cross-site requests to the given resource.
/// </summary>
/// <param name="value">
/// The HTTP Cross-Origin-Resource-Policy response header value.
/// </param>
/// <remarks>
/// Defaults to "same-origin" (<see cref="CrossOriginResourceOptions.SameOrigin"/>) which means that "Only requests from the same Origin (i.e. scheme + host + port) can read the resource."
///</remarks>
public static SecureHeadersMiddlewareConfiguration UseCrossOriginResourcePolicy(this SecureHeadersMiddlewareConfiguration config, CrossOriginResourceOptions value = CrossOriginResourceOptions.SameOrigin)
{
config.UseCrossOriginResourcePolicy = true;
config.CrossOriginResourcePolicy = new CrossOriginResourcePolicy(value);
return config;
}

Expand Down
1 change: 1 addition & 0 deletions src/Extensions/SecureHeadersMiddlewareExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public static SecureHeadersMiddlewareConfiguration BuildDefaultConfiguration()
.UseCacheControl()
.RemovePoweredByHeader()
.UseXssProtection()
.UseCrossOriginResourcePolicy()
.Build();
}

Expand Down
67 changes: 67 additions & 0 deletions src/Models/CrossOriginResourcePolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
namespace OwaspHeaders.Core.Models
{
/// <summary>
/// Cross-Origin-Resource-Policy
/// This response header(also named CORP) allows to define a policy that lets web sites and applications opt in to protection
/// against certain requests from other origins(such as those issued with elements like<script> and <img>), to mitigate speculative
/// side-channel attacks, like Spectre, as well as Cross-Site Script Inclusion(XSSI) attacks(source Mozilla MDN).
/// </summary>
public class CrossOriginResourcePolicy : IConfigurationBase
{
/// <summary>
/// Only requests from the same Origin (i.e. scheme + host + port) can read the resource.
/// </summary>
public const string SameOriginValue = "same-origin";
/// <summary>
/// Only requests from the same Site can read the resource.
/// </summary>
public const string SameSiteValue = "same-site";
/// <summary>
/// Requests from any Origin (both same-site and cross-site) can read the resource.
/// Browsers are using this policy when an CORP header is not specified.
/// </summary>
public const string CrossOriginValue = "cross-origin";

public enum CrossOriginResourceOptions
{
/// <summary>
/// <see cref="SameOriginValue"/>
/// </summary>
SameOrigin,
/// <summary>
/// <see cref="SameSiteValue"/>
/// </summary>
SameSite,
/// <summary>
/// <see cref="CrossOriginValue"/>
/// </summary>
CrossOrigin
};

public CrossOriginResourceOptions OptionValue { get; set; }

public CrossOriginResourcePolicy(CrossOriginResourceOptions value = CrossOriginResourceOptions.SameOrigin)
{
OptionValue = value;
}

/// <summary>
/// Builds the HTTP header value
/// </summary>
/// <returns>A string representing the HTTP header value</returns>
public string BuildHeaderValue()
{
switch (OptionValue)
{
case CrossOriginResourceOptions.CrossOrigin:
return CrossOriginValue;
case CrossOriginResourceOptions.SameSite:
return SameSiteValue;
case CrossOriginResourceOptions.SameOrigin:
default:
return SameOriginValue;
}
}

}
}
7 changes: 7 additions & 0 deletions src/Models/SecureHeadersMiddlewareConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public class SecureHeadersMiddlewareConfiguration

public bool RemoveXPoweredByHeader { get; set; }

/// <summary>
/// Indicates whether the response should use Cross-Origin-Resource-Policy
/// </summary>
public bool UseCrossOriginResourcePolicy { get; set; }

/// <summary>
/// The HTTP Strict Transport Security configuration to use
/// </summary>
Expand Down Expand Up @@ -107,5 +112,7 @@ public class SecureHeadersMiddlewareConfiguration
/// The Expect-CT configuration to use
/// </summary>
public ExpectCt ExpectCt { get; set; }

public CrossOriginResourcePolicy CrossOriginResourcePolicy { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/OwaspHeaders.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>An ASP.NET Core Middleware which adds the OWASP recommended HTTP headers for enhanced security.</Description>
<VersionPrefix>6.1.0</VersionPrefix>
<VersionPrefix>7.0.0</VersionPrefix>
<Authors>Jamie Taylor</Authors>
<AssemblyName>OwaspHeaders.Core</AssemblyName>
<TargetFramework>netstandard2.0</TargetFramework>
Expand Down
2 changes: 1 addition & 1 deletion src/OwaspHeadersCore.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<id>OwaspHeaders.Core</id>
<version>6.1.0</version>
<version>7.0.0</version>
<authors>GaProgMan</authors>
<owners>GaProgMan</owners>
<readme>docs\README-NuGet.md</readme>
Expand Down
6 changes: 6 additions & 0 deletions src/SecureHeadersMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ public async Task InvokeAsync(HttpContext httpContext)
httpContext.TryRemoveHeader(Constants.ServerHeaderName);
}

if(_config.UseCrossOriginResourcePolicy)
{
httpContext.TryAddHeader(Constants.CrossOriginResourcePolicyHeaderName,
_config.CrossOriginResourcePolicy.BuildHeaderValue());
}

// Call the next middleware in the chain
await _next(httpContext);
}
Expand Down
31 changes: 31 additions & 0 deletions tests/SecureHeadersInjectedTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -475,4 +475,35 @@ public async Task Invoke_CacheControl_HeaderIsNotPresent()
Assert.False(headerNotPresentConfig.UseCacheControl);
Assert.False(_context.Response.Headers.ContainsKey(Constants.CacheControlHeaderName));
}

[Fact]
public async Task Invoke_CrossOriginResourcePolicyHeaderName_HeaderIsPresent()
{
// 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 Invoke_CrossOriginResourcePolicyHeaderName_HeaderIsNotPresent()
{
// 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));
}
}

0 comments on commit 433cbb7

Please sign in to comment.