How to add security headers to your ASP.NET Core

By Tan Lee Published on Nov 08, 2024  423
To add security headers to your ASP.NET Core application, you can use middleware that adds the appropriate headers to HTTP responses.

 You can make a section in your web.config that looks something like this.

<configuration>
  <system.webServer>
    <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>
</configuration>

You can also use NWebsec to help you add security headers to ASP.NET Core by translating it to Startup.cs configure Pipeline like this:

app.UseHsts(options => options.MaxAge(days: 30));
app.UseXContentTypeOptions();
app.UseXXssProtection(options => options.EnabledWithBlockMode());
app.UseXfo(options => options.SameOrigin());
app.UseReferrerPolicy(opts => opts.NoReferrerWhenDowngrade());
 
app.UseCsp(options => options
    .DefaultSources(s => s.Self()
        .CustomSources("data:")
        .CustomSources("https:"))
    .StyleSources(s => s.Self()
        .CustomSources("cdn.datatables.net","cdnjs.cloudflare.com","cdn.jsdelivr.net","fonts.googleapis.com")
        .UnsafeInline()
    )
    .ScriptSources(s => s.Self()
           .CustomSources("cdn.datatables.net","cdn.jsdelivr.net","www.googletagmanager.com","cdn.syndication.twimg.com","cdnjs.cloudflare.com")
        .UnsafeInline()
        .UnsafeEval()
    )
); 

NWebSec is a popular open-source library designed to enhance the security of ASP.NET Core applications by providing middleware for automatically adding a wide range of HTTP security headers. These headers are essential for defending against various web security vulnerabilities, such as Cross-Site Scripting (XSS), clickjacking, and content injection.

NWebSec does not yet support the experimental HTTP header Feature-Policy, which is used to declare server-side restrictions on certain browser features.

For example, you can use Feature-Policy to prevent the use of the webcam or other client-side features, helping to protect your site from malicious scripts that might try to access these features.

Feature-Policy: camera 'none';

This would block the use of the webcam on your site, reducing the risk of exploitation by injected scripts.

You can add the Feature-Policy header to all responses as shown below.

//Feature-Policy
app.Use(async (context, next) =>
{
    context.Response.Headers.Append("Feature-Policy", "xr-spatial-tracking 'none';wake-lock 'none';publickey-credentials-get 'none';picture-in-picture 'none';payment 'none';navigation-override 'none';execution-while-out-of-viewport 'none';execution-while-not-rendered 'none';encrypted-media 'none';document-domain 'none';display-capture 'none';autoplay 'none';ambient-light-sensor 'none';accelerometer 'none';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';usb 'none'");
    await next.Invoke();
});