diff --git a/README-NuGet.md b/README-NuGet.md
index 558bb09..7dbd234 100644
--- a/README-NuGet.md
+++ b/README-NuGet.md
@@ -31,15 +31,17 @@ This will add a number of default HTTP headers to all responses from your server
The following is an example of the response headers from version 9.0.0 (taken on November 19th, 2024)
```http
-cache-control: max-age=31536000,private
-content-security-policy: script-src 'self';object-src 'self';block-all-mixed-content;upgrade-insecure-requests;
-cross-origin-resource-policy: same-origin
-referrer-policy: no-referrer
-strict-transport-security: max-age=31536000;includeSubDomains
-x-content-type-options: nosniff
-x-frame-options: DENY
-x-permitted-cross-domain-policies: none;
-x-xss-protection: 0
+strict-transport-security: max-age=31536000;includesubdomains
+x-frame-options: deny
+x-content-type-options: nosniff
+content-security-policy: script-src 'self';object-src 'self';block-all-mixed-content;upgrade-insecure-requests;
+x-permitted-cross-domain-policies: none
+referrer-policy: no-referrer
+cross-origin-resource-policy: same-origin
+cache-control: max-age=0,no-store
+cross-origin-opener-policy: same-origin
+cross-origin-embedder-policy: same-require-corp
+x-xss-protection: 0
```
Please note: The above example contains only the headers added by the Middleware.
diff --git a/README.md b/README.md
index 5b78e24..a2750c6 100644
--- a/README.md
+++ b/README.md
@@ -55,15 +55,17 @@ This will add a number of default HTTP headers to all responses from your server
The following is an example of the response headers from version 9.0.0 (taken on November 19th, 2024)
```http
-cache-control: max-age=31536000,private
-content-security-policy: script-src 'self';object-src 'self';block-all-mixed-content;upgrade-insecure-requests;
-cross-origin-resource-policy: same-origin
-referrer-policy: no-referrer
-strict-transport-security: max-age=31536000;includeSubDomains
-x-content-type-options: nosniff
-x-frame-options: DENY
-x-permitted-cross-domain-policies: none;
-x-xss-protection: 0
+strict-transport-security: max-age=31536000;includesubdomains
+x-frame-options: deny
+x-content-type-options: nosniff
+content-security-policy: script-src 'self';object-src 'self';block-all-mixed-content;upgrade-insecure-requests;
+x-permitted-cross-domain-policies: none
+referrer-policy: no-referrer
+cross-origin-resource-policy: same-origin
+cache-control: max-age=0,no-store
+cross-origin-opener-policy: same-origin
+cross-origin-embedder-policy: same-require-corp
+x-xss-protection: 0
```
Please note: The above example contains only the headers added by the Middleware.
diff --git a/changelog.md b/changelog.md
index a3294d2..f27c8a3 100644
--- a/changelog.md
+++ b/changelog.md
@@ -4,17 +4,17 @@ This changelog represents all the major (i.e. breaking) changes made to the Owas
## TL;DR
-| Major Version Number | Changes |
-|----------------------|-------------------------------------------------------------------------|
-| 9 | Removed support for both .NET 6 and .NET 7 as these are no longer supported by Microsoft. It also adds support for .NET 9. |
-| 8 | Removed support for ASP .NET Core on .NET Framework workflows; example and test projects now have OwaspHeaders.Core prefix, re-architected some of the test classes |
-| 7 | Added Cross-Origin-Resource-Policy header to list of defaults; simplified the use of the middleware in Composite Root/Program.cs |
-| 6 | Removes Expect-CT Header from the list of default headers |
-| 5 | XSS Protection is now hard-coded to return "0" if enabled |
-| 4 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
uses .NET Standard 2.0
Removed XSS Protection header from defaults |
-| 3 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 2.0 |
-| 2 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Core 2.0 |
-| 1 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 1.4 |
+| Major Version Number | Changes |
+|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 9 | Removed support for both .NET 6 and .NET 7 as these are no longer supported by Microsoft. It also adds support for .NET 9.
A number of small optimisation have been made to the middleware's `Invoke` method
Added support for both Cross-Origin-Opener-Policy (CORP) and Cross-Origin-Embedder-Policy (COEP) headers |
+| 8 | Removed support for ASP .NET Core on .NET Framework workflows; example and test projects now have OwaspHeaders.Core prefix, re-architected some of the test classes |
+| 7 | Added Cross-Origin-Resource-Policy header to list of defaults; simplified the use of the middleware in Composite Root/Program.cs |
+| 6 | Removes Expect-CT Header from the list of default headers |
+| 5 | XSS Protection is now hard-coded to return "0" if enabled |
+| 4 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
uses .NET Standard 2.0
Removed XSS Protection header from defaults |
+| 3 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 2.0 |
+| 2 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Core 2.0 |
+| 1 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 1.4 |
### Version 9
@@ -22,6 +22,10 @@ This version dropped support for .NET 6 and .NET 7, as they are no longer suppor
All projects in the [GitHub repo](https://github.com/GaProgMan/OwaspHeaders.Core) now build and run with either .NET 8 or .NET 9, whichever is present (deferring to the highest version number if both are present). As of November 19th, 2024 there are no new features in Version 9, so if you still need to use the NuGet package with .NET 6 or 7 please use Version 8 of the package.
+#### Verison 9.7.x
+
+This version saw the addition of both the [Cross-Origin-Opener-Policy](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cross-Origin-Opener-Policy/) (COEP) and [Cross-Origin-Embedder-Policy](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cross-Origin-Embedder-Policy/) (COEP) headers; bringing the total number of supported headers to 83% complete (or 10 of the 12 recommended headers and values).
+
#### Version 9.6.x
This version saw the addition of a number of _very_ small changes to the middleware's `Invoke` method which aimed to increase efficiency, reduce working memory usage, and increase execution speed.
diff --git a/docs/changelog.md b/docs/changelog.md
index 4428943..b1f5667 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,26 +1,20 @@
----
-title: Changelog
-layout: page
-nav_order: 7
----
-
# Changelog
This changelog represents all the major (i.e. breaking) changes made to the OwaspHeaders.Core project since it's inception. Early in the repo's development, GitHub's "releases" where used to release builds of the code repo. However shortly after it's inception, builds and releases where moved to [AppVeyor](https://ci.appveyor.com/project/GaProgMan/owaspheaders-core). Because of this, the releases on the GitHub repo became stale.
## TL;DR
-| Major Version Number | Changes |
-|----------------------|-------------------------------------------------------------------------|
-| 9 | Removed support for both .NET 6 and .NET 7 as these are no longer supported by Microsoft. It also adds support for .NET 9. |
-| 8 | Removed support for ASP .NET Core on .NET Framework workflows; example and test projects now have OwaspHeaders.Core prefix, re-architected some of the test classes |
-| 7 | Added Cross-Origin-Resource-Policy header to list of defaults; simplified the use of the middleware in Composite Root/Program.cs |
-| 6 | Removes Expect-CT Header from the list of default headers |
-| 5 | XSS Protection is now hard-coded to return "0" if enabled |
-| 4 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
uses .NET Standard 2.0
Removed XSS Protection header from defaults |
-| 3 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 2.0 |
-| 2 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Core 2.0 |
-| 1 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 1.4 |
+| Major Version Number | Changes |
+|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 9 | Removed support for both .NET 6 and .NET 7 as these are no longer supported by Microsoft. It also adds support for .NET 9.
A number of small optimisation have been made to the middleware's `Invoke` method
Added support for both Cross-Origin-Opener-Policy (CORP) and Cross-Origin-Embedder-Policy (COEP) headers |
+| 8 | Removed support for ASP .NET Core on .NET Framework workflows; example and test projects now have OwaspHeaders.Core prefix, re-architected some of the test classes |
+| 7 | Added Cross-Origin-Resource-Policy header to list of defaults; simplified the use of the middleware in Composite Root/Program.cs |
+| 6 | Removes Expect-CT Header from the list of default headers |
+| 5 | XSS Protection is now hard-coded to return "0" if enabled |
+| 4 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
uses .NET Standard 2.0
Removed XSS Protection header from defaults |
+| 3 | Uses builder pattern to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 2.0 |
+| 2 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Core 2.0 |
+| 1 | Uses `secureHeaderSettings.json` and default config loader to create instances of `SecureHeadersMiddlewareConfiguration` class
also uses .NET Standard 1.4 |
### Version 9
@@ -28,6 +22,10 @@ This version dropped support for .NET 6 and .NET 7, as they are no longer suppor
All projects in the [GitHub repo](https://github.com/GaProgMan/OwaspHeaders.Core) now build and run with either .NET 8 or .NET 9, whichever is present (deferring to the highest version number if both are present). As of November 19th, 2024 there are no new features in Version 9, so if you still need to use the NuGet package with .NET 6 or 7 please use Version 8 of the package.
+#### Verison 9.7.x
+
+This version saw the addition of both the [Cross-Origin-Opener-Policy](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cross-Origin-Opener-Policy/) (COEP) and [Cross-Origin-Embedder-Policy](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cross-Origin-Embedder-Policy/) (COEP) headers; bringing the total number of supported headers to 83% complete (or 10 of the 12 recommended headers and values).
+
#### Version 9.6.x
This version saw the addition of a number of _very_ small changes to the middleware's `Invoke` method which aimed to increase efficiency, reduce working memory usage, and increase execution speed.
diff --git a/docs/configuration/Cross-Origin-Embedder-Policy.md b/docs/configuration/Cross-Origin-Embedder-Policy.md
new file mode 100644
index 0000000..41033ee
--- /dev/null
+++ b/docs/configuration/Cross-Origin-Embedder-Policy.md
@@ -0,0 +1,53 @@
+---
+title: Cross-Origin-Opener-Policy
+nav_order: 10
+parent: Configuration
+layout: page
+---
+
+The Mozilla Developer Network describes the Cross-Origin-Embedder-Policy (COEP) header like this:
+
+{: .quote }
+> The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding cross-origin resources into the document.
+>
+> source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
+
+A COEP header can be added in one of two ways, either using the default middleware options:
+
+```csharp
+app.UseSecureHeadersMiddleware();
+```
+
+The above adds the COEP header with a `require-corp` value.
+
+Or by creating an instance of the `SecureHeadersMiddlewareBuilder` class using the following code:
+
+```csharp
+var customConfig = SecureHeadersMiddlewareBuilder
+ .CreateBuilder()
+ .UseCrossOriginResourcePolicy()
+ .UseCrossOriginEmbedderPolicy()
+ .Build();
+
+app.UseSecureHeadersMiddleware(customConfig);
+```
+
+{: .warning }
+> It is important to note that the recommended value for this header requires the presence of the
+> [Cross-Origin-Resource-Policy (CORP) header](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cross-Origin-Resource-Policy/)
+> in order to work.
+> As such, if you add the COEP header without the CORP header, OwaspHeaders.Core will raise an ArgumentException.
+
+The above adds the COEP header with a `require-corp` value.
+
+## Full Options
+
+The COEP header object (known internally as `CrossOriginEmbedderPolicy`) has the following options:
+
+- enum: `CrossOriginEmbedderOptions`
+
+The values available for the `CrossOriginEmbedderOptions` enum are:
+
+- `UnsafeNoneValue`
+- `RequireCorp`
+
diff --git a/docs/configuration/Cross-Origin-Opener-Policy.md b/docs/configuration/Cross-Origin-Opener-Policy.md
index 8f0f41b..280f735 100644
--- a/docs/configuration/Cross-Origin-Opener-Policy.md
+++ b/docs/configuration/Cross-Origin-Opener-Policy.md
@@ -43,7 +43,7 @@ The COOP header object (known internally as `CrossOriginOpenerPolicy`) has the f
The values available for the `CrossOriginOpenerOptions` enum are:
-- `CrossOrigin`
-- `SameSite`
+- `UnsafeNone`
+- `SameOriginAllowPopups`
- `SameOrigin`
diff --git a/docs/index.md b/docs/index.md
index ba57509..c03ad5d 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -88,7 +88,7 @@ The following list displays the status of all the current (as of Dec 27th, 2024)
- [ ✅ ] [Cache-Control](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cache-Control/)
- [ ❌ ] Clear-Site-Data
- [ ✅ ] [Cross-Origin-Opener-Policy](https://gaprogman.github.io/OwaspHeaders.Core/configuration/Cross-Origin-Opener-Policy/)
-- [ ❌ ] Cross-Origin-Embedder-Policy
+- [ ✅ ] Cross-Origin-Embedder-Policy
- [ ❌ ] Permissions-Policy
Key:
diff --git a/src/Constants.cs b/src/Constants.cs
index e0f1ed4..5effed4 100644
--- a/src/Constants.cs
+++ b/src/Constants.cs
@@ -26,5 +26,8 @@ public static class Constants
public const string ExpectCtHeaderName = "Expect-CT";
public const string CrossOriginResourcePolicyHeaderName = "Cross-Origin-Resource-Policy";
+
public const string CrossOriginOpenerPolicyHeaderName = "Cross-Origin-Opener-Policy";
+
+ public const string CrossOriginEmbedderPolicyHeaderName = "Cross-Origin-Embedder-Policy";
}
diff --git a/src/Extensions/SecureHeadersMiddlewareBuilder.cs b/src/Extensions/SecureHeadersMiddlewareBuilder.cs
index 5fdf161..9fd8002 100644
--- a/src/Extensions/SecureHeadersMiddlewareBuilder.cs
+++ b/src/Extensions/SecureHeadersMiddlewareBuilder.cs
@@ -341,7 +341,29 @@ public static SecureHeadersMiddlewareConfiguration UseCrossOriginOpenerPolicy(
}
///
- /// Used to set a list of URLs that the we want the middleware to NOT operate on
+ /// The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding
+ /// cross-origin resources into the document.
+ /// Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
+ ///
+ ///
+ /// The HTTP Cross-Origin-Embedder-Policy response header value.
+ ///
+ ///
+ /// Defaults to "require-corp" ()
+ /// which means that "Only requests from the same Origin (i.e. scheme + host + port) can read the resource."
+ ///
+ public static SecureHeadersMiddlewareConfiguration UseCrossOriginEmbedderPolicy(
+ this SecureHeadersMiddlewareConfiguration config,
+ CrossOriginEmbedderPolicy.CrossOriginEmbedderOptions value =
+ CrossOriginEmbedderPolicy.CrossOriginEmbedderOptions.RequireCorp)
+ {
+ config.UseCrossOriginEmbedderPolicy = true;
+ config.CrossOriginEmbedderPolicy = new CrossOriginEmbedderPolicy(value);
+ return config;
+ }
+
+ ///
+ /// Used to set a list of URLs that we want the middleware to NOT operate on
///
///
///
diff --git a/src/Extensions/SecureHeadersMiddlewareExtensions.cs b/src/Extensions/SecureHeadersMiddlewareExtensions.cs
index 0e0ae6c..11854c9 100644
--- a/src/Extensions/SecureHeadersMiddlewareExtensions.cs
+++ b/src/Extensions/SecureHeadersMiddlewareExtensions.cs
@@ -34,6 +34,7 @@ public static SecureHeadersMiddlewareConfiguration BuildDefaultConfiguration(
.UseXssProtection()
.UseCrossOriginResourcePolicy()
.UseCrossOriginOpenerPolicy()
+ .UseCrossOriginEmbedderPolicy()
.SetUrlsToIgnore(urlIgnoreList)
.Build();
}
diff --git a/src/Guards/BoolValueGuardClausesArgumentException.cs b/src/Guards/BoolValueGuardClausesArgumentException.cs
new file mode 100644
index 0000000..4f40a75
--- /dev/null
+++ b/src/Guards/BoolValueGuardClausesArgumentException.cs
@@ -0,0 +1,12 @@
+namespace OwaspHeaders.Core.Guards;
+
+public static class BoolValueGuardClauses
+{
+ public static void MustBeTrue(bool value, string parameterName)
+ {
+ if (!value)
+ {
+ ArgumentExceptionHelper.RaiseNotTrueException(parameterName);
+ }
+ }
+}
diff --git a/src/Helpers/ArgumentExceptionHelper.cs b/src/Helpers/ArgumentExceptionHelper.cs
index 54681b2..003be73 100644
--- a/src/Helpers/ArgumentExceptionHelper.cs
+++ b/src/Helpers/ArgumentExceptionHelper.cs
@@ -10,6 +10,14 @@ public static void RaiseException(string argumentName)
throw new ArgumentException($"No value for {argumentName} was supplied");
}
+ ///
+ /// Used to raise an whenever a bool argument should be true, but is not
+ ///
+ public static void RaiseNotTrueException(string argumentName)
+ {
+ throw new ArgumentException($"Value for {argumentName} must be true");
+ }
+
public static void RaiseArgumentNullException(string argumentName, string message)
{
throw new ArgumentNullException(argumentName, message);
diff --git a/src/Models/CrossOriginEmbedderPolicy.cs b/src/Models/CrossOriginEmbedderPolicy.cs
new file mode 100644
index 0000000..3ff65ea
--- /dev/null
+++ b/src/Models/CrossOriginEmbedderPolicy.cs
@@ -0,0 +1,73 @@
+namespace OwaspHeaders.Core.Models;
+
+///
+/// Cross-Origin-Embedder-Policy
+/// This response header (also named COEP) prevents a document from loading any
+/// cross-origin resources that don’t explicitly grant the document permission
+/// (source Mozilla MDN).
+/// 💡 To fully understand where CORP and COEP work:
+/// - CORP applies on the loaded resource side (resource owner).
+/// - COEP applies on the “loader” of the resource side (consumer of the resource).
+/// MDN Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
+///
+public class CrossOriginEmbedderPolicy : IConfigurationBase
+{
+ ///
+ /// Cross-Origin-Embedder-Policy
+ /// This response header (also named COEP) prevents a document from loading any
+ /// cross-origin resources that don’t explicitly grant the document permission
+ /// (source Mozilla MDN).
+ /// 💡 To fully understand where CORP and COEP work:
+ /// - CORP applies on the loaded resource side (resource owner).
+ /// - COEP applies on the “loader” of the resource side (consumer of the resource).
+ /// MDN Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
+ ///
+ public CrossOriginEmbedderPolicy(CrossOriginEmbedderOptions value =
+ CrossOriginEmbedderOptions.RequireCorp)
+ {
+ OptionValue = value;
+ }
+
+ ///
+ /// Allows the document to fetch cross-origin resources without giving explicit permission
+ /// through the CORS protocol or the Cross-Origin-Resource-Policy header (it is the default value).
+ ///
+ public const string UnsafeNoneValue = "unsafe-none";
+
+ ///
+ /// A document can only load resources from the same origin, or resources explicitly
+ /// marked as loadable from another origin.
+ ///
+ public const string RequireCorp = "same-require-corp";
+
+ public enum CrossOriginEmbedderOptions
+ {
+ ///
+ ///
+ ///
+ UnsafeNone,
+
+ ///
+ ///
+ ///
+ RequireCorp
+ };
+
+ private CrossOriginEmbedderOptions OptionValue { get; }
+
+ ///
+ /// Builds the HTTP header value
+ ///
+ /// A string representing the HTTP header value
+ public string BuildHeaderValue()
+ {
+ switch (OptionValue)
+ {
+ case CrossOriginEmbedderOptions.UnsafeNone:
+ return UnsafeNoneValue;
+ case CrossOriginEmbedderOptions.RequireCorp:
+ default:
+ return RequireCorp;
+ }
+ }
+}
diff --git a/src/Models/SecureHeadersMiddlewareConfiguration.cs b/src/Models/SecureHeadersMiddlewareConfiguration.cs
index aaf0240..84f2d58 100644
--- a/src/Models/SecureHeadersMiddlewareConfiguration.cs
+++ b/src/Models/SecureHeadersMiddlewareConfiguration.cs
@@ -72,6 +72,11 @@ public class SecureHeadersMiddlewareConfiguration
///
public bool UseCrossOriginOpenerPolicy { get; set; }
+ ///
+ /// Indicates whether the response should use Cross-Origin-Embedder-Policy
+ ///
+ public bool UseCrossOriginEmbedderPolicy { get; set; }
+
///
/// The HTTP Strict Transport Security configuration to use
///
@@ -121,6 +126,8 @@ public class SecureHeadersMiddlewareConfiguration
public CrossOriginOpenerPolicy CrossOriginOpenerPolicy { get; set; }
+ public CrossOriginEmbedderPolicy CrossOriginEmbedderPolicy { get; set; }
+
///
/// A list of URLs that, when requested, should be ignored completely by
/// the middleware
diff --git a/src/OwaspHeaders.Core.csproj b/src/OwaspHeaders.Core.csproj
index b6dd031..6e99b1a 100644
--- a/src/OwaspHeaders.Core.csproj
+++ b/src/OwaspHeaders.Core.csproj
@@ -8,7 +8,7 @@
OwaspHeaders.Core
- 9.7.0
+ 9.7.1
Jamie Taylor
RJJ Software Ltd
MIT
diff --git a/src/SecureHeadersMiddleware.cs b/src/SecureHeadersMiddleware.cs
index eee081d..48641d8 100644
--- a/src/SecureHeadersMiddleware.cs
+++ b/src/SecureHeadersMiddleware.cs
@@ -132,6 +132,16 @@ private FrozenDictionary GenerateRelevantHeaders()
_config.CrossOriginOpenerPolicy.BuildHeaderValue());
}
+ if (_config.UseCrossOriginEmbedderPolicy)
+ {
+ if (!_config.UseCrossOriginResourcePolicy)
+ {
+ BoolValueGuardClauses.MustBeTrue(_config.UseCrossOriginResourcePolicy, nameof(_config.UseCrossOriginResourcePolicy));
+ }
+ temporaryDictionary.Add(Constants.CrossOriginEmbedderPolicyHeaderName,
+ _config.CrossOriginEmbedderPolicy.BuildHeaderValue());
+ }
+
return temporaryDictionary.ToFrozenDictionary();
}
diff --git a/tests/OwaspHeaders.Core.Tests/CustomHeaders/CrossOriginOptionsTests.cs b/tests/OwaspHeaders.Core.Tests/CustomHeaders/CrossOriginOptionsTests.cs
index 19fe764..3d6d484 100644
--- a/tests/OwaspHeaders.Core.Tests/CustomHeaders/CrossOriginOptionsTests.cs
+++ b/tests/OwaspHeaders.Core.Tests/CustomHeaders/CrossOriginOptionsTests.cs
@@ -40,6 +40,54 @@ public async Task When_UseCrossOriginOpenerPolicyCalled_Header_Is_Present()
_context.Response.Headers[Constants.CrossOriginOpenerPolicyHeaderName]);
}
+ [Fact]
+ public async Task When_UseCrossOriginEmbedderPolicyCalled_Header_Is_Present()
+ {
+ // arrange
+ var headerPresentConfig =
+ SecureHeadersMiddlewareBuilder.CreateBuilder()
+ .UseCrossOriginResourcePolicy()
+ .UseCrossOriginEmbedderPolicy().Build();
+ var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);
+
+ // act
+ await secureHeadersMiddleware.InvokeAsync(_context);
+
+ // assert
+ Assert.True(headerPresentConfig.UseCrossOriginEmbedderPolicy);
+ Assert.True(headerPresentConfig.UseCrossOriginResourcePolicy);
+
+ Assert.True(_context.Response.Headers.ContainsKey(Constants.CrossOriginResourcePolicyHeaderName));
+ Assert.Equal(CrossOriginResourcePolicy.SameOriginValue,
+ _context.Response.Headers[Constants.CrossOriginResourcePolicyHeaderName]);
+
+ Assert.True(_context.Response.Headers.ContainsKey(Constants.CrossOriginEmbedderPolicyHeaderName));
+ Assert.Equal(CrossOriginEmbedderPolicy.RequireCorp,
+ _context.Response.Headers[Constants.CrossOriginEmbedderPolicyHeaderName]);
+ }
+
+ [Fact]
+ public async Task When_UseCrossOriginEmbedderPolicyCalled_But_UseCrossOriginResourcePolicy_NotSupplied_Header_Is_Not_Present()
+ {
+ // arrange
+ var headerPresentConfig =
+ SecureHeadersMiddlewareBuilder.CreateBuilder()
+ .UseCrossOriginEmbedderPolicy().Build();
+ var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerPresentConfig);
+
+ // act
+ var exception = await Record.ExceptionAsync(() => secureHeadersMiddleware.InvokeAsync(_context));
+
+ // assert
+ Assert.NotNull(exception);
+ Assert.IsType(exception);
+
+ Assert.True(headerPresentConfig.UseCrossOriginEmbedderPolicy);
+ Assert.False(headerPresentConfig.UseCrossOriginResourcePolicy);
+
+ Assert.False(_context.Response.Headers.ContainsKey(Constants.CrossOriginEmbedderPolicyHeaderName));
+ }
+
[Fact]
public async Task When_UseCrossOriginResourcePolicyNotCalled_Header_Not_Present()
{
@@ -71,5 +119,21 @@ public async Task When_UseCrossOriginOpenerPolicyNotCalled_Header_Not_Present()
Assert.False(headerNotPresentConfig.UseCrossOriginOpenerPolicy);
Assert.False(_context.Response.Headers.ContainsKey(Constants.CrossOriginOpenerPolicyHeaderName));
}
+
+ [Fact]
+ public async Task When_UseCrossOriginEmbedderPolicyNotCalled_Header_Not_Present()
+ {
+ // arrange
+ var headerNotPresentConfig = SecureHeadersMiddlewareBuilder.CreateBuilder()
+ .Build();
+ var secureHeadersMiddleware = new SecureHeadersMiddleware(_onNext, headerNotPresentConfig);
+
+ // act
+ await secureHeadersMiddleware.InvokeAsync(_context);
+
+ // assert
+ Assert.False(headerNotPresentConfig.UseCrossOriginEmbedderPolicy);
+ Assert.False(_context.Response.Headers.ContainsKey(Constants.CrossOriginEmbedderPolicyHeaderName));
+ }
}
diff --git a/tests/OwaspHeaders.Core.Tests/GuardClauses/HeaderValueGuardClausesStringValues.cs b/tests/OwaspHeaders.Core.Tests/GuardClauses/HeaderValueGuardClausesStringValues.cs
index 3987880..ab6ebda 100644
--- a/tests/OwaspHeaders.Core.Tests/GuardClauses/HeaderValueGuardClausesStringValues.cs
+++ b/tests/OwaspHeaders.Core.Tests/GuardClauses/HeaderValueGuardClausesStringValues.cs
@@ -1,5 +1,36 @@
namespace OwaspHeaders.Core.Tests.GuardClauses;
+public class BoolValueGuardClauses
+{
+ [Fact]
+ public void TrueValue_ShouldNotThrow_ArgumentException()
+ {
+ // Arrange
+ var argName = Guid.NewGuid().ToString();
+
+ // Act
+ var exception = Record.Exception(() => Guards.BoolValueGuardClauses.MustBeTrue(true, argName));
+
+ // Assert
+ Assert.Null(exception);
+ }
+
+ [Fact]
+ public void FalseValue_ShouldThrow_ArgumentException()
+ {
+ // Arrange
+ var argName = Guid.NewGuid().ToString();
+
+ // Act
+ var exception = Record.Exception(() => Guards.BoolValueGuardClauses.MustBeTrue(false, argName));
+
+ // Assert
+ Assert.NotNull(exception);
+ Assert.IsType(exception);
+ Assert.Contains(argName, exception.Message);
+ }
+}
+
public class HeaderValueGuardClauses
{
[Theory]