百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
N

NetEscapades.AspNetCore.SecurityHeaders

> 编程语言
开源

一个小程序,可允许在 ASP.NET Core 网站中添加安全性头部

849 stars0 点赞0 次浏览
访问官网GitHub

工具介绍

一个小程序,可允许在 ASP.NET Core 网站中添加安全性头部

NetEscapades.AspNetCore.SecurityHeaders

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 add package NetEscapades.AspNetCore.SecurityHeaders --version 1.3.1

Usage

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


  
    netcoreapp5.0
  

  
    
  
  

There are various ways to configure the headers for your application.

In the simplest scenario, add the middleware to your ASP.NET Core application by configuring it as part of your normal Startup pipeline (or WebApplication in .NET 6+).

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; - only applied to HTTPS responses
  • X-Frame-Options: Deny
  • Referrer-Policy: strict-origin-when-cross-origin
  • Content-Security-Policy: object-src 'none'; form-action 'self'; frame-ancestors 'none'
  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: credentialless
  • Cross-Origin-Resource-Policy: same-site

Note that these policies represent a "safe" set of minimum defaults that should be valid for most sites, but are not the most secure they could be. You are advised to think about what features you need, and to restrict them where possible. For example, a stronger Content Security Policy should be used where possible, as well as a Permissions Policy.

Customising the security headers added to responses

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.

…

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(maxAgeInSeconds: 63072000);

    app.UseSecurityHeaders(policyCollection);

    // other middleware e.g. static files, MVC etc  
}

There is also a convenience overload for UseSecurityHeaders that takes an Action, instead of requiring you to instantiate a HeaderPolicyCollection yourself:

public void Configure(IApplicationBuilder app)
{
    app.UseSecurityHeaders(policies =>
        policies
            .AddDefaultSecurityHeaders()
            .AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 63072000)
    );

    // other middleware e.g. static files, MVC etc  
}

Applying different headers to different endpoints

In some situations, you may need to apply different security headers to different endpoints. For example, you may want to have a very restrictive Content-Security-Policy by default, but then have a more relaxed on specific endpoints that require it. This is supported, but requires more configuration.

1. Configure your policies using AddSecurityHeaderPolicies()

You can configure named and default policies by calling AddSecurityHeaderPolicies() on IServiceCollection. You can configure the default policy to use, as well as any named policies. For example, the following configures the default policy (used for all requests that are not customised for an endpoint), and a named policy:

var builder = WebApplication.CreateBuilder();

//  Call AddSecurityHeaderPolicies()
builder.Services.AddSecurityHeaderPolicies()
    .SetDefaultPolicy(policy => policy.AddDefaultSecurityHeaders()) //  Configure the default policy
    .AddPolicy("CustomPolicy", policy => policy.AddCustomHeader("X-Custom", "SomeValue")); //  Configure named policies

2. Call UseSecurityHeaders() early in the middleware pipeline

The security headers middleware can only add headers to all requests if it is early in the middleware pipeline, so it's important to add the headers middleware at the start of your middleware pipeline by calling UseSecurityHeaders(). For example:

var builder = WebApplication.CreateBuilder();

//  Configure policies as shown previously
builder.Services.AddSecurityHeaderPolicies()
    .SetDefaultPolicy(policy => policy.AddDefaultSecurityHeaders())
    .AddPolicy("CustomPolicy", policy => policy.AddCustomHeader("X-Custom", "SomeValue"));

var app = builder.Build();

// Add the middleware to the start of your pipeline
// 
app.UseSecurityHeaders();

app.UseStaticFiles(); // other middleware
app.UseAuthentication();
app.UseRouting(); 

app.UseAuthorization();

app.MapGet("/", () => "Hello world");
app.Run();

3. Apply custom policies to endpoints

To apply a non-default policy to an endpoint, use the WithSecurityHeadersPolicy(policy) endpoint extension method, and pass in the name of the policy to apply:

var builder = WebApplication.CreateBuilder();

builder.Services.AddSecurityHeaderPolicies()
    .SetDefaultPolicy(policy => policy.AddDefaultSecurityHeaders())
    .AddPolicy("CustomPolicy", policy => policy.AddCustomHeader("X-Custom", "SomeValue"));

var app = builder.Build();

app.UseSecurityHeaders();

app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting(); 

app.UseAuthorization();

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

If you're using MVC controllers or Razor Pages, you can apply the [SecurityHeadersPolicy(policyName)] attribute to your endpoints:

public class HomeController : ControllerBase
{
    [SecurityHeadersPolicy("CustomHeader")] //  Apply a named policy to the endpoint
    public IActionResult Index()
    {
        return View();
    }
}

Security headers are applied just before the response is sent. If you use the configuration described above, then the policy to apply is determined as follows, with the first applicable policy selected:

  1. If an endpoint has been selected, and a named policy is applied, use that.
  2. If a named or policy instance is passed to the SecurityHeadersMiddleware(), use that.
  3. If the default policy has been set using SetDefaultPolicy(), use that.
  4. Otherwise, apply the default headers (those added by AddDefaultSecurityHeaders())

Customizing the headers per request

If you need to use a different set of security headers for certain endpoints in your application, then configuring named policies as described above is the best approach.

However, sometimes you need even more customization on a per-request basis. For example, perhaps you have a multi-tenant application, and you need to apply different headers based on a header in the request (or the response) that identifies the tenant. In this situation, you don't know at application startup which set of headers to apply.

To customize the final HeaderPolicyCollection used for a request, you can use the SetPolicySelector() method available on IServiceCollection.AddSecurityHeaderPolicies(). This method take a Func<> argument which is passed a context object, and must return an IReadOnlyHeaderPolicyCollection. The SetPolicySelector() argument is invoked for every request, just before the final selected policy is applied, and allows you to change the IReadOnlyHeaderPolicyCollection to apply.

The following code shows how to use a dependency injected service in combination with the SetPolicySelector() method. This isn't necessary, but rather shows that you can completely customise the applied headers in any way you need.

…

Note that you should avoid creating a HeaderPolicyCollection from scratch on each request. Instead, cache policies for multiple requests where possible. However, if you need to build a new policy based on the policy passed in the context object, you can create a mutable copy by calling IReadOnlyHeaderPolicyCollection.Copy(), adding/updating policies as required, and returning the HeaderPolicyCollection.

Applying different headers to JSON API endpoints

As described in the OWASP guidance about security headers, APIs that return only JSON do not require all the security headers added by AddDefaultSecurityHeaders(). If your API may return HTML or content other than JSON, it may be safest to use the default security headers nonetheless. If not, you can use the AddDefaultApiSecurityHeaders() method to apply a subset of headers. This method sets the following headers:

  • X-Content-Type-Options: nosniff
  • Strict-Transport-Security: max-age=31536000; - only applied to HTTPS responses
  • X-Frame-Options: Deny
  • Content-Security-Policy: default-src: none; frame-ancestors 'none'
  • Referrer-Policy: no-referrer
  • Permissions-Policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()
  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp
  • Cross-Origin-Resource-Policy: same-site

Apply it in the same way to your header policy collection:

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddDefaultApiSecurityHeaders();

    app.UseSecurityHeaders(policyCollection);
}

this is equivalent to

public void Configure(IApplicationBuilder app)
{
    var policyCollection = new HeaderPolicyCollection()
        .AddFrameOptionsDeny()
        .AddContentTypeOptionsNoSniff()
        .AddStrictTransportSecurityMaxAge()
        .RemoveServerHeader()
        .AddContentSecurityPolicy(builder =>
        {
            builder.AddDefaultSrc().None();
            builder.AddFrameAncestors().None();
        })
        .AddReferrerPolicyNoReferrer()
        .AddPermissionsPolicyWithDefaultSecureDirectives();

    app.UseSecurityHeaders(policyCollection);
}

RemoveServerHeader

One point to be aware of is that the RemoveServerHeader method will rarely (ever?) be sufficient to remove the Server head

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

C#hacktoberfest

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言