Implement security headers for an ASP.NET Core

By Tan Lee Published on Jun 24, 2025  49
This article demonstrates how to implement security headers in a .NET 9 application. The security headers are added using the FoxLearn.AspNetCore.SecurityHeaders NuGet package by FoxLearn.

FoxLearn.AspNetCore.SecurityHeaders is a lightweight library for adding common security headers to ASP.NET Core applications.

security headers

After publishing your website, you can use https://securityheaders.com to test your security headers.

This package simplifies the process of applying essential HTTP security headers such as Content-Security-PolicyStrict-Transport-SecurityX-Content-Type-Options, and more to your ASP.NET Core middleware pipeline, helping protect your web applications from common vulnerabilities.

You can install the package via the .NET CLI:

dotnet add package FoxLearn.SecurityHeaders.AspNetCore

Or via the NuGet UI in Visual Studio by searching for FoxLearn.AspNetCore.SecurityHeaders

asp.net core security headres

To enable and customize security headers in your ASP.NET Core application, configure the services and middleware using the provided extension methods. Add the service registration in your Startup.cs or Program.cs file:

builder.Services.AddSecurityHeaderPolicies(options =>
{
    options.AddCrossOriginResourcePolicy(x => x.SameOrigin())
    .AddFrameOptionsDeny()
    .AddContentTypeOptionsNoSniff()
    .AddReferrerPolicy(ReferrerPolicy.StrictOrigin)
    .AddStrictTransportSecurity()
    .AddPermissionsPolicy(policy =>
    {
        policy.AddAccelerometer().Self().For("https://foxlearn.com");
        policy.AddMicrophone();
    });
});

var app = builder.Build();

...

app.UseSecurityHeaders(); // Required

To fully control the headers returned, create a HeaderPolicyCollection and define your own set of headers including any custom headers you may need:

// Define a custom header policy
var policy = new HeaderPolicyCollection()
    .AddFrameOptionsDeny()
    .AddReferrerPolicyStrictOriginWhenCrossOrigin();

builder.Services.AddSecurityHeaderPolicies(options =>
{
    options.AddPolicy("CustomPolicy", policy => policy.AddCustomHeader("X-Custom", "SomeValue"));
});

// Apply your custom policy globally or on a per-endpoint basis:
app.UseSecurityHeaders(policy);    // Apply custom global policy
app.UseEndpointSecurityHeaders();  // Enable attribute-based usage

Next, Apply a Policy to a Controller Action

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    [SecurityHeadersPolicy("CustomPolicy")]
    public IActionResult Index()
    {
        return View();
    }
}

Apply custom policies to endpoints

If you need to apply a custom (non-default) security header policy to a specific endpoint, use the .WithSecurityHeadersPolicy("PolicyName") extension method during endpoint mapping:

app.MapGet("/", () => "Hello world")
   .WithSecurityHeadersPolicy("CustomPolicy"); // Apply a named policy to this endpoint

If you're using Kestrel, the Server header can be removed in the Program class. For IIS, you’ll likely need to remove it via the web.config file.

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.AddServerHeader = false;
});