Giter Site home page Giter Site logo

supertr0n / netescapades.aspnetcore.securityheaders Goto Github PK

View Code? Open in Web Editor NEW

This project forked from andrewlock/netescapades.aspnetcore.securityheaders

0.0 0.0 0.0 140 KB

Small package to allow adding security headers to ASP.NET Core websites

License: MIT License

C# 88.23% PowerShell 4.85% Shell 2.44% HTML 4.49%

netescapades.aspnetcore.securityheaders's Introduction

NetEscapades.AspNetCore.SecurityHeaders

Build status

NuGet MyGet CI

A small package to allow adding security headers to ASP.NET Core websites

Installing

Install using the NetEscapades.AspNetCore.SecurityHeaders NuGet package from the Visual Studio Package Manager Console:

PM> Install-Package NetEscapades.AspNetCore.SecurityHeaders

Or using the dotnet CLI

dotnet package add Install-Package NetEscapades.AspNetCore.SecurityHeaders

Usage

When you install the package, it should be added to your .csproj. Alternatively, you can add it directly by adding:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="0.5.0" />
  </ItemGroup>
  
</Project>

Simply add the middleware to your ASP.NET Core application by configuring it as part of your normal Startup pipeline. Note that the order of middleware matters, so to apply the headers to all requests it should be configured first in your pipeline.

To use the default security headers for your application, add the middleware using:

public void Configure(IApplicationBuilder app)
{
    app.UseSecurityHeaders()
    
    // other middleware e.g. static files, MVC etc  
}

This adds the following headers to all responses that pass through the middleware:

  • X-Content-Type-Options: nosniff
  • Strict-Transport-Security: max-age=31536000; includeSubDomains - only applied to HTTPS responses
  • X-Frame-Options: Deny - only applied to text/html responses
  • X-XSS-Protection: 1; mode=block - only applied to text/html responses
  • Referrer-Policy: strict-origin-when-cross-origin - only applied to text/html responses
  • Content-Security-Policy: object-src 'none'; form-action 'self'; frame-ancestors 'none' - only applied to text/html responses

Customising the security headers added to reponses

To customise the headers returned, you should create an instance of a HeaderPolicyCollection and add the required policies to it. There are helper methods for adding a number of security-focused header values to the collection, or you can alternatively add any header by using the CustomHeader type. For example, the following would set a number of security headers, and a custom header X-My-Test-Header.

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddFrameOptionsDeny()
        .AddXssProtectionBlock()
        .AddContentTypeOptionsNoSniff()
        .AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAge: 60 * 60 * 24 * 365) // maxage = one year in seconds
        .AddReferrerPolicyStrictOriginWhenCrossOrigin()
        .RemoveServerHeader()
        .AddContentSecurityPolicy(builder =>
        {
            builder.AddObjectSrc().None();
            builder.AddFormAction().Self();
            builder.AddFrameAncestors().None();
        });
        .AddCustomHeader("X-My-Test-Header", "Header value");
    
    app.UseSecurityHeaders(policyCollection)
    
    // other middleware e.g. static files, MVC etc  
}

The security headers above are also encapsulated in another extension method, so you could rewrite it more tersely using

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddDefaultSecurityHeaders()
        .AddCustomHeader("X-My-Test-Header", "Header value");
    
    app.UseSecurityHeaders(policyCollection)
    
    // other middleware e.g. static files, MVC etc  
}

If you want to use the default security headers, but change one specific header, you can simply add another header to the default collection. For example, the following uses the default headers, but changes the max-age on the Strict-Transport-Security header:

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddDefaultSecurityHeaders()
        .AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAge: 63072000);
    
    app.UseSecurityHeaders(policyCollection)
    
    // other middleware e.g. static files, MVC etc  
}

RemoveServerHeader

One point to be aware of is that the RemoveServerHeader method will rarely (ever?) be sufficient to remove the Server header from your output. If any subsequent middleware in your application pipeline add the header, then this will be able to remove it. However Kestrel will generally add the Server header too late in the pipeline to be able to modify it.

Luckily, Kestrel exposes it's own mechanism to allow you to prevent it being added:

var host = new WebHostBuilder()
    .UseKestrel(options => options.AddServerHeader = false)
    //...

In Program.cs, when constructing your app's WebHostBuilder, configure the KestrelServerOptions to prevent the Server tag being added.

AddContentSecurityPolicy

The Content-Security-Policy (CSP) headder is a very powerful header that can protect your website from a wide range of attacks. However, it's also totally possible to create a CSP header that completely breaks your app.

The CSP has a dizzying array of options, only some of which are implemented in this project. Consequently, I highly recommend reading this post by Scott Helme, in which he discusses the impact of each "directive". I also highly recommend using the "report only" version of the header when you start. This won't break your site, but will report instances that it would be broken, by providing reports to a service such as report-uri.com.

Set the header to report-only by using the AddContentSecurityPolicyReportOnly() extension. For example:

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddContentSecurityPolicyReportOnly(builder => // report-only 
        {
            // configure policies
        }); 
}

or by by passing true to the AddContentSecurityPolicy command

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddContentSecurityPolicy(builder =>
        {
            // configure policies
        },
        asReportOnly: true); // report-only 
}

You configure your CSP policy when you configure your HeaderPolicyCollection in Startup.Configure. For example:

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddContentSecurityPolicy(builder =>
        {
            builder.AddUpgradeInsecureRequests() // upgrade-insecure-requests
            builder.AddBlockAllMixedContent() // block-all-mixed-content

            builder.AddReportUri() // report-uri: https://report-uri.com
                .To("https://report-uri.com");

            builder.AddDefaultSrc() // default-src 'self' http://testUrl.com
                .Self()
                .From("http://testUrl.com");

            builder.AddConnectSrc() // connect-src 'self' http://testUrl.com
                .Self()
                .From("http://testUrl.com");

            builder.AddFontSrc() // font-src 'self'
                .Self();

            builder.AddObjectSrc() // object-src 'none'
                .None();
                
            builder.AddFormAction() // form-action 'self'
                .Self();
                
            builder.AddImgSrc() // img-src https:
                .OverHttps();
            
            builder.AddScriptSrc() // script-src 'self' 'unsafe-inline' 'unsafe-eval' 'report-sample'
                .Self()
                .UnsafeInline()
                .UnsafeEval()
                .ReportSample();
            
            builder.AddStyleSrc() // style-src 'self' 'strict-dynamic'
                .Self()
                .StrictDynamic();
            
            builder.AddMediaSrc() // media-src https:
                .OverHttps();

            builder.AddFrameAncestors() // frame-ancestors 'none'
                .None();
            
            builder.AddBaseUri() // base-ri 'self'
                .Self();
                
            builder.AddFrameSource() // frame-src http://testUrl.com
                .From("http://testUrl.com");
            
            // You can also add arbitrary extra directives: plugin-types application/x-shockwave-flash"
            builder.AddCustomDirective("plugin-types", "application/x-shockwave-flash");
            
        });
        .AddCustomHeader("X-My-Test-Header", "Header value");
    
    app.UseSecurityHeaders(policyCollection)
    
    // other middleware e.g. static files, MVC etc  
}

Additional Resources

Note, Building on Travis is currently disabled, due to issues with the mono framework. For details, see

netescapades.aspnetcore.securityheaders's People

Contributors

andrewlock avatar prajaybasu avatar trevorpilley avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.