AspNetCore.SecurityHeaders

repository·master·Indexed 42 days ago

https://github.com/juunas11/aspnetcore-security-headers

A middleware library for ASP.NET Core that simplifies the addition of security headers, including Content Security Policy (CSP), Strict Transport Security (HSTS), and Public Key Pinning (HPKP). It provides a fluent API for configuring policies and includes support for CSP nonces via Razor Tag Helpers.

Tokens
1.9K
Snippets
5
Records
5
Agent score
5%

What's inside AspNetCore.SecurityHeaders

  1. Use CSP Nonces for Inline Scripts and Styles

    master

    To allow inline <script> and <style> elements without using unsafe-inline, you can use CSP nonces. This requires three steps:

    1. Register CSP Services: In ConfigureServices, call services.AddCsp(nonceByteAmount: n) where n is the number of bytes for the nonce.
    2. Enable Nonce in CSP Policy: In your app.UseCsp configuration, call .AddNonce() on the relevant resource classes (e.g., AllowScripts and AllowStyles).
    3. Use Tag Helper in Razor Views:
      • Add the tag helper to _ViewImports.cshtml: @addTagHelper *, Joonasw.AspNetCore.SecurityHeaders.
      • Apply the asp-add-nonce="true" attribute to your script or style tags.
    // 1. Register services
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCsp(nonceByteAmount: 32);
    }
    
    // 2. Update CSP definition
    app.UseCsp(csp => {
        csp.AllowScripts.FromSelf().AddNonce();
        csp.AllowStyles.FromSelf().AddNonce();
    });
    @* 3. Use in Razor View *@
    <head>
      <script asp-add-nonce="true">
        console.log("Hello");
      </script>
      <style asp-add-nonce="true">
        h1 { color: red; }
      </style>
    </head>
  2. Configure Content Security Policy (CSP)

    master

    Use app.UseCsp to define a Content Security Policy. The configuration allows you to define rules for various resource classes (Scripts, Styles, Images, etc.) and control where they can be loaded from using methods like .FromSelf(), .From(domain), or .FromNowhere() (to block entirely).

    Key features include:

    • SetReportOnly(): Sends violation reports without blocking the resources.
    • ReportViolationsTo(path): Specifies the endpoint for CSP violation reports.
    • OnSendingHeader: A callback to conditionally skip sending the CSP header (e.g., for specific API routes).
    // 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");
    
        // Allow Images from:
        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
        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;
        };
    });
  3. Configure Strict Transport Security (HSTS)

    master

    Use app.UseStrictTransportSecurity to enable HSTS. You must provide an HstsOptions object which allows you to specify the caching period, whether to include subdomains, and whether to allow preloading.

    // Enable Strict Transport Security with a 30-day caching period
    // Do not include subdomains
    // Do not allow preload
    app.UseStrictTransportSecurity(new HstsOptions(TimeSpan.FromDays(30), includeSubDomains: false, preload: false));
  4. Configure Public Key Pinning (HPKP)

    master

    Use app.UseHpkp to configure certificate pinning. The configuration uses a fluent API to set the max age, add SHA-256 pins, set the policy to Report-Only mode, and specify a violation reporting endpoint.

    // 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");
    });