A Professional ASP.NET Core API - Security Headers
With the help of headers, your website could send some useful information to the browser. Let’s see how it is possible to add more protection to your website.
To add a header for each request, we can use middleware.
HTTPS is pretty awesome. It not only encrypts the traffic between the client and server so others can’t see it, but also prevents others from modifying the content. So it also provides integrity. And being that you can now have HTTPS for free with services like Let’s Encrypt, most apps should start to look into using HTTPS.
This is my favorite. Specifying headers in middleware can be done in C# code by creating one or more pieces of middleware. Most examples in this post will use this approach. In short, you either create a new middleware class or call the
Use method directly in the
Configure method in
app.Use(async (context, next) =>
The code adds a new header named
Header-Name to all responses. It’s important to call the
Use method before calling
UseMvc, and similar.
The following list examines an important part of application headers.
It tells the browser: “You shall only access this URL over a secure connection.”. By submitting a
Strict-Transport-Security header, the browser saves it and redirects itself to the HTTPS version without making an insecure call.
X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a
<object>. Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites.
context.Response.Headers.Add("x-frame-options", new StringValues("DENY"));
Change the value to
SAMEORIGIN to allow your site to
The X-Frame-Options header is automatically added with the value SAMEORIGIN when enabling
If you don’t want to add it automatically
X-Permitted-Cross-Domain-Policies HTTP response header can be used to indicate whether or not an Adobe products such as Adobe Reader should be allowed to render a page. Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other applications.
context.Response.Headers.Add("X-Permitted-Cross-Domain-Policies", new StringValues("none"));
X-XSS-Protection response header is a feature that stops pages from loading when they detect reflected
cross-site scripting (XSS) attacks. Although these protections are largely unnecessary in modern browsers when sites implement a strong
'unsafe-inline'), they can still provide protections for users of older web browsers that don’t yet support CSP.
context.Response.Headers.Add("x-xss-protection", new StringValues("1; mode=block"));
enabled and the mode of
block will block the browser from rendering the page.
MIME-type sniffing is an attack where a hacker tries to exploit missing metadata on served files. The header can be added in middleware:
The value of
nosniff will prevent primarily old browsers from MIME-sniffing.
When you click a link on a website, the calling URL is automatically transferred to the linked site. Unless this is necessary, you should disable it using the
There are a lot of possible values for this header, like
same-origin that will set the referrer as long as the user stays on the same website.
Feature-Policy header tells the browser which platform features your website needs. Most web apps won’t need to access the microphone or the vibrator functions available on mobile browsers. Why not be explicit about it to avoid imported scripts or framed pages to do things you don’t expect:
context.Response.Headers.Add("Feature-Policy", new StringValues(
Like ASP.NET, ASP.NET Core will return the
X-Powered-By header. This happens when you host your website on IIS. This also means that you simply cannot remove the header in middleware, since this is out of hands for ASP.NET Core.
web.config to the rescue:
Like X-Powered-By, IIS kindly identify itself in the
Server header. While hackers probably quickly find out anyway, you should still make it as hard as possible by removing the header. There’s a dedicated security feature available in
web.config to do that:
To disable the
Server header from
Kestrel, you need to set
Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints. This helps guard against cross-site scripting attacks (XSS).
context.Response.Headers.Add("Content-Security-Policy", new StringValues(
The Expect-CT header lets sites opt in to reporting and/or enforcement of Certificate Transparency requirements, to prevent the use of misissued certificates for that site from going unnoticed.
context.Response.Headers.Add("Expect-CT", new StringValues("max-age=0, enforce, report-uri=\"https://example.report-uri.com/r/d/ct/enforce\""));
public sealed class SecurityHeadersMiddleware
You should call athe above custom middleware as the following:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
You can check you have correctly set the security headers by using the following service: https://securityheaders.com
NWebsec consists of several security libraries for ASP.NET applications.
Small package to allow adding security headers to ASP.NET Core websites
Most of the information in this article has gathered from various references.