Adding Security Headers to ASP.NET Core 3.1 Web Api

I am in need to add some security headers to my new ASP.NET Core 3.1 Web API. In MVC and webform I used to do with below codes in web.config file:

<httpProtocol>
      <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000"/>
        <add name="X-Content-Type-Options" value="nosniff"/>
        <add name="X-Xss-Protection" value="1; mode=block"/>
        <add name="X-Frame-Options" value="SAMEORIGIN"/>
        <add name="Content-Security-Policy" value="default-src https:; img-src * 'self' data: https:; style-src 'self' 'unsafe-inline' www.google.com platform.twitter.com cdn.syndication.twimg.com fonts.googleapis.com; script-src 'self' 'unsafe-inline' 'unsafe-eval' www.google.com cse.google.com cdn.syndication.twimg.com platform.twitter.com platform.instagram.com www.instagram.com cdn1.developermedia.com cdn2.developermedia.com apis.google.com www.googletagservices.com adservice.google.com securepubads.g.doubleclick.net ajax.aspnetcdn.com ssl.google-analytics.com az416426.vo.msecnd.net/;"/>
        <add name="Referrer-Policy" value="no-referrer-when-downgrade"/>
        <add name="Feature-Policy" value="geolocation 'none';midi 'none';notifications 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment 'none';"/>
        <remove name="X-Powered-By" />
        <remove name="X-AspNet-Version" />
        <remove name="Server" />
      </customHeaders>
</httpProtocol>

I know we can have a web.config file in .NET Core too but I want to achieve this by adding custom codes in startup class. I have found few articles using some NUGET packages but it would be awesome if someone can give me a clear picture to add security headers in .Net Core.
Thanks in advance.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Create a middleware class CustomResponseHeaderMiddleware like this in your code:

public class CustomResponseHeaderMiddleware
{
    private readonly RequestDelegate _next;

    public CustomResponseHeaderMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        //To add Headers AFTER everything you need to do this
        context.Response.OnStarting(state =>
        {
            var httpContext = (HttpContext)state;
            httpContext.Response.Headers.Add("Strict-Transport-Security", "max-age=31536000");
            httpContext.Response.Headers.Add("X-Content-Type-Options", "nosniff");
            httpContext.Response.Headers.Add("X-Xss-Protection", "1; mode=block");
            httpContext.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
            //... and so on
            return Task.CompletedTask;
        }, context);

        await _next(context);
    }
}

And register this middleware in startup.cs file

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ....
    app.UseMiddleware(typeof(CustomResponseHeaderMiddleware));
    
    app.UseMvc();
}

Method 2

You can use NWebsec package to add security policy like this.

app.UseCsp(options =>
{
    options.BlockAllMixedContent()
    .ScriptSources(s => s.Self())
    .StyleSources(s => s.Self())
    .StyleSources(s => s.UnsafeInline())
    .FontSources(s => s.Self())
    .FormActions(s => s.Self())
    .FrameAncestors(s => s.Self())
    .ImageSources(s => s.Self());
});
app.UseXfo(option =>
{
    option.Deny();
});
app.UseXXssProtection(option =>
{
    option.EnabledWithBlockMode();
});
app.UseXContentTypeOptions();
app.UseReferrerPolicy(opts => opts.NoReferrer());

Remove server header

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseKestrel(options =>
        {
            options.AddServerHeader = false;
        })
        .UseStartup<Startup>();

or

<configuration> 
  <system.webServer>
    <security>
      <requestFiltering removeServerHeader="true" />
    </security>
    <httpProtocol>
      <customHeaders>
        <remove name="X-Powered-By" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

Adding HSTS

app.UseHsts(options =>
{
    options.MaxAge(days: 365).IncludeSubdomains().Preload();
});

Adding Feature-Policy

app.Use(async (context, next) =>
{
    if (context.Response.Headers.All(x => x.Key != "Feature-Policy"))
        context.Response.Headers.Add("Feature-Policy", new[] { "accelerometer 'none'; camera 'none'; geolocation 'self'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'" });

    await next();
});


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x