Adding HTTP Headers to improve Security in an ASP.NET MVC Core application

This article shows how to add headers in a HTTPS response for an ASP.NET Core MVC application. The HTTP headers help protect against some of the attacks which can be executed against a website. is used to test and validate the HTTP headers as well as F12 in the browser. NWebSec is used to add most of the HTTP headers which improve security for the MVC application. Thanks to Scott Helme for creating, and André N. Klingsheim for creating NWebSec.



2021-04-07 Add link to
2020-12-11 Updated to .NET 5
2019-10-06 Updated to .NET Core 3.0
2018-11-10 Updated to .NET Core 2.2, small corrections
2018-05-07 Updated to .NET Core 2.1 preview 2, new Identity Views, 2FA Authenticator, IHttpClientFactory, bootstrap 4.1.0
2018-02-09 Updated, added feedback from different sources, removing extra headers, add form actions to the CSP configuration, adding info about CAA.

A simple ASP.NET Core MVC application was created and deployed to Azure. can be used to validate the headers in the application. The deployed application used in this post can be found here:

Testing the default application using gives the following results with some room for improvement.

Fixing this in ASP.NET Core is pretty easy due to NWebSec. Add the NuGet package to the project.

<PackageReference Include="NWebsec.AspNetCore.Middleware" Version="3.0.0" />

Or using the NuGet Package Manager in Visual Studio


All the NWebSec code configurations are added to the Startup.cs class in the Configure method.

Add the Strict-Transport-Security Header

By using HSTS, you can force that all communication is done using HTTPS. If you want to force HTTPS on the first request from the browser, you can use the HSTS preload:

app.UseHsts(hsts => hsts.MaxAge(365).IncludeSubdomains());

Add the X-Content-Type-Options Header

The X-Content-Type-Options can be set to no-sniff to prevent content sniffing.


Add the Referrer Policy Header

This allows us to restrict the amount of information being passed on to other sites when referring to other sites. This is set to no referrer.

app.UseReferrerPolicy(opts => opts.NoReferrer());

Scott Helme write a really good post on this:

Add the X-XSS-Protection Header

The HTTP X-XSS-Protection response header is a feature of Internet Explorer, Chrome and Safari that stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. (Text copied from here)

app.UseXXssProtection(options => options.EnabledWithBlockMode());

Add the X-Frame-Options Header

You can use the X-frame-options Header to block iframes and prevent click jacking attacks.

app.UseXfo(options => options.Deny());

Add the Content-Security-Policy Header

Content Security Policy can be used to prevent all sort of attacks, XSS, click-jacking attacks, or prevent mixed mode (HTTPS and HTTP). The following configuration works for ASP.NET Core MVC applications, the mixed mode is activated, styles can be read from unsafe inline, due to the razor controls, or tag helpers, and everything can only be loaded from the same origin.

app.UseCsp(opts => opts.BlockAllMixedContent() 
	.StyleSources(s => s.Self()) 
	.StyleSources(s => s.UnsafeInline()) 
	.FontSources(s => s.Self()) 
	.FormActions(s => s.Self()) 
	.FrameAncestors(s => s.Self()) 
	.ImageSources(s => s.Self()) 
	.ScriptSources(s => s.Self()) 

Due to this CSP configuration, the public CDNs need to be removed from the MVC application which are per default included in the dotnet template for an ASP.NET Core MVC application.

NWebSec configuration in the Startup

//Registered before static files to always set header
app.UseHsts(hsts => hsts.MaxAge(365).IncludeSubdomains());
app.UseReferrerPolicy(opts => opts.NoReferrer());
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseXfo(options => options.Deny());

app.UseCsp(opts => opts
	.StyleSources(s => s.Self())
	.StyleSources(s => s.UnsafeInline())
	.FontSources(s => s.Self())
	.FormActions(s => s.Self())
	.FrameAncestors(s => s.Self())
	.ImageSources(imageSrc => imageSrc.Self())
	.ImageSources(imageSrc => imageSrc.CustomSources("data:"))
	.ScriptSources(s => s.Self())

When the application is tested again, things look much better.

Or view the headers in the browser, for example F12 in Chrome, and then the network view:

Here’s the test results for this demo.

Removing the extra infomation from the Headers

You could also remove the extra information from the HTTPS headers, for example X-Powered-By, or Server, so that less information is sent to the client.

Remove the server headers from the kestrel server, by using the UseKestrel extension method.

.UseKestrel(c => c.AddServerHeader = false)

Add a web.config to your project with the following settings:

<?xml version="1.0" encoding="UTF-8"?>
    <httpRuntime enableVersionHeader="false"/>
      <requestFiltering removeServerHeader="true" />
        <remove name="X-Powered-By"/>

Now by viewing the response in the browser, you can see some unrequired headers have been removed.

Further steps in hardening the application:


You can fix your domain to a selected amount of authorities. You can control the authorities which can issue the certs for your domain. This reduces the risk, that another cert authority produces a cert for your domain to a different person. This can be checked here:

Or configured here:

Then add it to the hosting provider.

Use a WAF

You could also add a WAF, for example to only expose public URLs and not private ones, or protect against DDoS attacks.

Certificate testing

The certificate should also be tested and validated. is a good test tool.

Here’s the result for the cert used in the demo project.

I would be grateful for feedback, or suggestions to improve this.


How to Implement Security HTTP Headers to Prevent Vulnerabilities?


  1. […] Adding HTTP Headers to improve Security in an ASP.NET MVC Core application (Damien Bowden) […]

  2. […] Adding HTTP Headers to improve Security in an ASP.NET MVC Core application – Damien Bowden […]

  3. […] Adding HTTP Headers to improve Security in an ASP.NET MVC Core application (Damien Bowden) […]

  4. […] only explains how to add custom header on mvc using IIS. You can checkout a blogpost by Damienbod which explains how to do it on core MVC aplication by configuring the Startup […]

  5. This works great, but why is there no control for set cookie: secure?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: