Joonasw.AspNetCore.SecurityHeaders 2.3.0

.NET Standard 1.5
There is a newer version of this package available.
See the version list below for details.
dotnet add package Joonasw.AspNetCore.SecurityHeaders --version 2.3.0
NuGet\Install-Package Joonasw.AspNetCore.SecurityHeaders -Version 2.3.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Joonasw.AspNetCore.SecurityHeaders" Version="2.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Joonasw.AspNetCore.SecurityHeaders --version 2.3.0
#r "nuget: Joonasw.AspNetCore.SecurityHeaders, 2.3.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Joonasw.AspNetCore.SecurityHeaders as a Cake Addin
#addin nuget:?package=Joonasw.AspNetCore.SecurityHeaders&version=2.3.0

// Install Joonasw.AspNetCore.SecurityHeaders as a Cake Tool
#tool nuget:?package=Joonasw.AspNetCore.SecurityHeaders&version=2.3.0

Add CSP, HSTS or HPKP headers to an ASP.NET Core app

This library allows you to add Content Security Policy, Strict Transport Security and Public Key Pin headers via middleware.

You can get the library from NuGet: https://www.nuget.org/packages/Joonasw.AspNetCore.SecurityHeaders

Example configuration

// Enable Strict Transport Security with a 30-day caching period
// Do not include subdomains
// Do not allow preload
app.UseHsts(new HstsOptions(TimeSpan.FromDays(30), includeSubDomains: false, preload: false));

// Use certificate pinning with:
// - 30-day caching period
// - One pin in SHA-256 form
// - Report-Only = Invalid certificate should not be reported, but:
// - Report problems to /hpkp-report
app.UseHpkp(hpkp =>
{
    hpkp.UseMaxAgeSeconds(30 * 24 * 60 * 60)
        .AddSha256Pin("nrmpk4ZI3wbRBmUZIT5aKAgP0LlKHRgfA2Snjzeg9iY=")
        .SetReportOnly()
        .ReportViolationsTo("/hpkp-report");
});

// Content Security Policy
app.UseCsp(csp =>
{
    // If nothing is mentioned for a resource class, allow from this domain
    csp.ByDefaultAllow
        .FromSelf();

    // Allow JavaScript from:
    csp.AllowScripts
        .FromSelf() //This domain
        .From("localhost:1591") //These two domains
        .From("ajax.aspnetcdn.com");

    // CSS allowed from:
    csp.AllowStyles
        .FromSelf()
        .From("ajax.aspnetcdn.com");

    csp.AllowImages
        .FromSelf();

    // HTML5 audio and video elemented sources can be from:
    csp.AllowAudioAndVideo
        .FromNowhere();

    // Contained iframes can be sourced from:
    csp.AllowFrames
        .FromNowhere(); //Nowhere, no iframes allowed

    // Allow AJAX, WebSocket and EventSource connections to:
    csp.AllowConnections
        .To("ws://localhost:1591")
        .To("http://localhost:1591")
        .ToSelf();

    // Allow fonts to be downloaded from:
    csp.AllowFonts
        .FromSelf()
        .From("ajax.aspnetcdn.com");

    // Allow object, embed, and applet sources from:
    csp.AllowPlugins
        .FromNowhere();

    // Allow other sites to put this in an iframe?
    csp.AllowFraming
        .FromNowhere(); // Block framing on other sites, equivalent to X-Frame-Options: DENY

    // Do not block violations, only report
    // This is a good idea while testing your CSP
    // Remove it when you know everything will work
    csp.SetReportOnly();
    // Where should the violation reports be sent to?
    csp.ReportViolationsTo("/csp-report");

    // Do not include the CSP header for requests to the /api endpoints
    csp.OnSendingHeader = context =>
    {
        context.ShouldNotSend = context.HttpContext.Request.Path.StartsWithSegments("/api");
        return Task.CompletedTask;
    };
});

Content Security Policy can be quite daunting. Here is a nice page to find out what the options do: https://content-security-policy.com/

For violation reports, I recommend using Scott Helme's Report URI service at https://report-uri.io/.

Nonces

CSP allows you to also specify a nonce value, which makes it easier to have inline script and style elements like this on a page:

<head>
  <script>
    console.log("Hello");
  </script>
  <style>
    h1 {
      color: red;
    }
  </style>
</head>

To allow them without nonces, you might have to use the unsafe-inline option.

Instead of doing that, we can add the following service in Startup:

public void ConfigureServices(IServiceCollection services)
{
    // ... other service registrations

    // Add services necessary for nonces in CSP, 32-byte nonces
    services.AddCsp(nonceByteAmount: 32);
}

Then you need to modify your CSP definition to include the nonce:

csp.AllowScripts
    .FromSelf()
    .From("localhost:1591")
    .From("ajax.aspnetcdn.com")
    .AddNonce(); //<----

csp.AllowStyles
    .FromSelf()
    .From("ajax.aspnetcdn.com")
    .AddNonce(); //<-----

Then to use the nonce tag helper, we need to import it in _ViewImports.cshtml:

@addTagHelper *, Joonasw.AspNetCore.SecurityHeaders

Then we just need to use it in the Razor view:

<head>
  <script asp-add-nonce="true">
    console.log("Hello");
  </script>
  <style asp-add-nonce="true">
    h1 {
      color: red;
    }
  </style>
</head>

Now a unique nonce is generated every request and inserted into the CSP header + the elements you want.

Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp1.0 netcoreapp1.1 netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard1.5 netstandard1.6 netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48 net481
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen30 tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Joonasw.AspNetCore.SecurityHeaders:

Package Downloads
RezisFramework

Package Description

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Joonasw.AspNetCore.SecurityHeaders:

Repository Stars
exceptionless/Exceptionless
Exceptionless server and jobs
Version Downloads Last updated
4.0.1 210,443 3/3/2022
3.0.0 668,804 10/24/2019
2.9.0 91,550 6/21/2019
2.8.1 86,743 1/1/2019
2.8.0 592 1/1/2019
2.7.0 63,994 8/11/2018
2.6.0 30,630 5/27/2018
2.5.1 4,209 5/1/2018
2.5.0 2,725 4/14/2018
2.4.1 955 4/14/2018
2.4.0 21,610 1/21/2018
2.3.0 1,853 1/6/2018
2.2.0 6,657 11/20/2017
2.1.0 7,251 10/29/2017
2.0.0 2,785 9/30/2017
1.1.2 14,620 7/14/2017
1.1.0 1,579 5/17/2017
1.0.1 3,412 1/23/2017
1.0.0 4,245 1/22/2017

Added ability to decide if CSP headers should be included in a request.