Skip to content

Commit

Permalink
Feature/cross origin opener policy (#160)
Browse files Browse the repository at this point in the history
* Added model for Cross-Origin-Opener-Policy

* Leveraged COOP models

* Added tests for COOP header

* Moved CORP model back to explicit constructor

* Added missing test for COOP in one-shot test

* Minor version bump

* Ran dotnet-format on codebase

* Checked off the COOP (Cross-Origin-Opener-Policy) header in list of supported headers

* Linked to docs files for some of the supported headers

* Moved detail about X-XSS-Protection header to a warning at the head of it's documentation

* Added docs page for Cross-Origin-Resource-Policy (CORP) header

* Altered order of Cache-Control header docs page

* Added docs page for the Cross-Origin-Opener-Policy (COOP) header

* Added links in index for CORP and COOP docs pages

---------

Co-authored-by: Jamie Taylor <[email protected]>
  • Loading branch information
GaProgMan and jamie-taylor-rjj authored Dec 27, 2024
1 parent b9a4671 commit a46c76b
Show file tree
Hide file tree
Showing 15 changed files with 338 additions and 53 deletions.
2 changes: 1 addition & 1 deletion docs/configuration/Cache-Control.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Cache-Control
nav_order: 7
nav_order: 8
parent: Configuration
layout: page
---
Expand Down
49 changes: 49 additions & 0 deletions docs/configuration/Cross-Origin-Opener-Policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Cross-Origin-Opener-Policy
nav_order: 9
parent: Configuration
layout: page
---

The Mozilla Developer Network describes the Cross-Origin-Opener-Policy (COOP) header like this:

{: .quote }
> The HTTP Cross-Origin-Opener-Policy (COOP) response header allows a website to control whether a new top-level
> document, opened using Window.open() or by navigating to a new page, is opened in the same browsing context group
> (BCG) or in a new browsing context group.
>
> source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
A COOP header can be added in one of two ways, either using the default middleware options:

```csharp
app.UseSecureHeadersMiddleware();
```

The above adds the COOP header with a `same-origin` value.

Or by creating an instance of the `SecureHeadersMiddlewareBuilder` class using the following code:

```csharp
var customConfig = SecureHeadersMiddlewareBuilder
.CreateBuilder()
.UseCrossOriginOpenerPolicy()
.Build();

app.UseSecureHeadersMiddleware(customConfig);
```

The above adds the COOP header with a `same-origin` value.

## Full Options

The COOP header object (known internally as `CrossOriginOpenerPolicy`) has the following options:

- enum: `CrossOriginOpenerOptions`

The values available for the `CrossOriginOpenerOptions` enum are:

- `CrossOrigin`
- `SameSite`
- `SameOrigin`

47 changes: 47 additions & 0 deletions docs/configuration/Cross-Origin-Resource-Policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Cross-Origin-Resource-Policy
nav_order: 7
parent: Configuration
layout: page
---

The Mozilla Developer Network describes the Cross-Origin-Resource-Policy (CORP) header like this:

{: .quote }
> The HTTP Cross-Origin-Resource-Policy response header indicates that the browser should block no-cors cross-origin or cross-site requests to the given resource.
>
> source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy
A CORP header can be added in one of two ways, either using the default middleware options:

```csharp
app.UseSecureHeadersMiddleware();
```

The above adds the CORP header with a `same-origin` value.

Or by creating an instance of the `SecureHeadersMiddlewareBuilder` class using the following code:

```csharp
var customConfig = SecureHeadersMiddlewareBuilder
.CreateBuilder()
.UseCrossOriginResourcePolicy()
.Build();

app.UseSecureHeadersMiddleware(customConfig);
```

The above adds the CORP header with a `same-origin` value.

## Full Options

The CORP header object (known internally as `CrossOriginResourcePolicy`) has the following options:

- enum: `CrossOriginResourceOptions`

The values available for the `CrossOriginResourceOptions` enum are:

- `CrossOrigin`
- `SameSite`
- `SameOrigin`

5 changes: 3 additions & 2 deletions docs/configuration/X-XSS-Protection.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ parent: Configuration
layout: page
---

{: .warning }
Both the OWASP Secure Headers Project and MDN recommend not using this header with any value other than "0", which disabled the XSS Auditor. This is due to the X-XSS-Protection header having been dropped from most modern browsers and that using it (with a value other than "0") can cause additional security issues to present themselves. The recommended path forward is to use a [Content-Security-Policy (CSP)](Content-Security-Policy.md) header.

The Mozilla Developer Network describes the X-XSS-Protection header like this:

{: .quote }
> The HTTP X-XSS-Protection response header was a feature of Internet Explorer, Chrome and Safari that stopped pages from loading when they detected reflected cross-site scripting (XSS) attacks. These protections are largely unnecessary in modern browsers when sites implement a strong Content-Security-Policy that disables the use of inline JavaScript ('unsafe-inline').
>
> source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
Both the OWASP Secure Headers Project and MDN recommend not using this header with any value other than "0", which disabled the XSS Auditor. This is due to the X-XSS-Protection header having been dropped from most modern browsers and that using it (with a value other than "0") can cause additional security issues to present themselves. The recommended path forward is to use a [Content-Security-Policy (CSP)](Content-Security-Policy.md) header.

As such, the only value that OwaspHeaders.Core supports for the X-XSS-Protection header is "0", and the header can be added in one of two ways:

```csharp
Expand Down
24 changes: 16 additions & 8 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,16 @@ This project is a work-in-progress, and headers will be added inline with Owasp

The following list displays the status of all the current (as of Dec 27th, 2024) recommended headers:

- [] Strict-Transport-Security
- [] X-Frame-Options
- [] X-Content-Type-Options
- [] [Strict-Transport-Security]
- [] [X-Frame-Options]
- [] [X-Content-Type-Options]
- [] Content-Security-Policy
- [] X-Permitted-Cross-Domain-Policies
- [] Referrer-Policy
- [] Cross-Origin-Resource-Policy
- [] Cache-Control
- [] [X-Permitted-Cross-Domain-Policies]
- [] [Referrer-Policy]
- [] [Cross-Origin-Resource-Policy]
- [] [Cache-Control]
- [] Clear-Site-Data
- [ ] Cross-Origin-Opener-Policy
- [ ] [Cross-Origin-Opener-Policy]
- [] Cross-Origin-Embedder-Policy
- [] Permissions-Policy

Expand Down Expand Up @@ -126,3 +126,11 @@ The `web.config` file will need to be copied to the server when the application
[Configuration]: https://gaprogman.github.io/OwaspHeaders.Core/configuration/
[this answer on ServerFault]: https://serverfault.com/a/1020784
[OWASP Secure Headers List]: https://owasp.org/www-project-secure-headers/#div-headers
[Strict-Transport-Security]: ./configuration/Strict-Transport-Security/
[X-Frame-Options]: ./configuration/X-Frame-Options/
[X-Content-Type-Options]: ./configuration/X-Content-Type-Options/
[X-Permitted-Cross-Domain-Policies]: ./configuration/X-Permitted-Cross-Domain-Policies/
[Referrer-Policy]: ./configuration/Referrer-Policy/
[Cross-Origin-Resource-Policy]: ./configuration/Cross-Origin-Resource-Policy/
[Cache-Control]: ./configuration/Cache-Control/
[Cross-Origin-Opener-Policy]: ./configuration/Cross-Origin-Opener-Policy/
1 change: 1 addition & 0 deletions src/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ 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";
}
23 changes: 23 additions & 0 deletions src/Extensions/SecureHeadersMiddlewareBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,29 @@ public static SecureHeadersMiddlewareConfiguration UseCrossOriginResourcePolicy(
return config;
}

/// <summary>
/// The HTTP Cross-Origin-Opener-Policy (COOP) response header allows a website to control
/// whether a new top-level document, opened using Window.open() or by navigating to a new
/// page, is opened in the same browsing context group (BCG) or in a new browsing context group.
/// Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy
/// </summary>
/// <param name="value">
/// The HTTP Cross-Origin-Opener-Policy response header value.
/// </param>
/// <remarks>
/// Defaults to "same-origin" (<see cref="CrossOriginOpenerPolicy.CrossOriginOpenerOptions.SameOrigin"/>)
/// which means that "Only requests from the same Origin (i.e. scheme + host + port) can read the resource."
///</remarks>
public static SecureHeadersMiddlewareConfiguration UseCrossOriginOpenerPolicy(
this SecureHeadersMiddlewareConfiguration config,
CrossOriginOpenerPolicy.CrossOriginOpenerOptions value =
CrossOriginOpenerPolicy.CrossOriginOpenerOptions.SameOrigin)
{
config.UseCrossOriginOpenerPolicy = true;
config.CrossOriginOpenerPolicy = new CrossOriginOpenerPolicy(value);
return config;
}

/// <summary>
/// Used to set a list of URLs that the we want the middleware to NOT operate on
/// </summary>
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()
.UseXssProtection()
.UseCrossOriginResourcePolicy()
.UseCrossOriginOpenerPolicy()
.SetUrlsToIgnore(urlIgnoreList)
.Build();
}
Expand Down
88 changes: 88 additions & 0 deletions src/Models/CrossOriginOpenerPolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
namespace OwaspHeaders.Core.Models;

/// <summary>
/// Cross-Origin-Opener-Policy.
/// The following text was taken from the OWASP Secure Headers Project:
/// This response header (also named COOP) allows you to ensure a top-level
/// document does not share a browsing context group with cross-origin documents.
/// COOP will process-isolate your document and potential attackers can’t access
/// to your global object if they were opening it in a popup, preventing a
/// set of cross-origin attacks dubbed XS-Leaks (https://xsleaks.dev/)
/// (source Mozilla MDN (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy)).


/// </summary>
public class CrossOriginOpenerPolicy : IConfigurationBase
{
/// <summary>
/// Cross-Origin-Opener-Policy.
/// The following text was taken from the OWASP Secure Headers Project:
/// This response header (also named COOP) allows you to ensure a top-level
/// document does not share a browsing context group with cross-origin documents.
/// COOP will process-isolate your document and potential attackers can’t access
/// to your global object if they were opening it in a popup, preventing a
/// set of cross-origin attacks dubbed XS-Leaks (https://xsleaks.dev/)
/// (source Mozilla MDN (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy)).
/// </summary>
public CrossOriginOpenerPolicy(CrossOriginOpenerOptions value =
CrossOriginOpenerOptions.SameOrigin)
{
OptionValue = value;
}

/// <summary>
/// Allows the document to be added to its opener’s browsing context group
/// unless the opener itself has a COOP of same-origin or same-origin-allow-popups (it is the default value).
/// </summary>
private const string UnsafeNoneValue = "unsafe-none";

/// <summary>
/// Only requests from the same Site can read the resource.
/// </summary>
private const string SameOriginAllowPopupsValue = "same-origin-allow-popups";

/// <summary>
/// Retains references to newly opened windows or tabs which either
/// don’t set COOP or which opt out of isolation by setting a COOP
/// of unsafe-none
/// </summary>
public const string SameOriginValue = "same-origin";

public enum CrossOriginOpenerOptions
{
/// <summary>
/// <see cref="UnsafeNoneValue"/>
/// </summary>
UnsafeNone,

/// <summary>
/// <see cref="SameOriginAllowPopupsValue"/>
/// </summary>
SameOriginAllowPopups,

/// <summary>
/// <see cref="SameOriginValue"/>
/// </summary>
SameOrigin
};

private CrossOriginOpenerOptions OptionValue { get; }

/// <summary>
/// Builds the HTTP header value
/// </summary>
/// <returns>A string representing the HTTP header value</returns>
public string BuildHeaderValue()
{
switch (OptionValue)
{
case CrossOriginOpenerOptions.SameOriginAllowPopups:
return SameOriginAllowPopupsValue;
case CrossOriginOpenerOptions.UnsafeNone:
return UnsafeNoneValue;
case CrossOriginOpenerOptions.SameOrigin:
default:
return SameOriginValue;
}
}
}
Loading

0 comments on commit a46c76b

Please sign in to comment.