At the user group meetup last week Damien Bod shared many valuable insights in how to protect your applications. Among the many tools he showed was securityheaders.com. Unfortunately for us, this test site calculated a very bad result for the user group site:
We took this result as a challenge to improve it quickly and to share what you need to do to improve this rating. Thanks to another tool Damien told us about it only took 10 minutes to get to the B rating.
Use NWebsec
NWebsec is a collection of security libraries for ASP.NET. These libraries work together to remove version headers, control cache headers, stop potentially dangerous redirects, and set important security headers. These security features are not new, but they are easily forgotten (as we demonstrated ourselves with the user group site). NWebsec helps you to implement them without much effort and explains the steps you have to do very well in their documentation.
For an ASP.NET Core app you can use this command in the package manager console to install this middleware in your web project:
1 |
Install-Package NWebsec.AspNetCore.Middleware |
Next open the Startup.cs
file and search for app.UseStaticFiles()
. You need to add these few lines from the getting started guide before and after the call to app.UseStaticFiles:
1 2 3 4 5 6 7 8 9 10 |
// Security - Registered before static files to always set header app.UseHsts(hsts => hsts.MaxAge(365)); app.UseXContentTypeOptions(); app.UseReferrerPolicy(opts => opts.NoReferrer()); app.UseStaticFiles(); // Security - Registered after static files, for dynamic content. app.UseXfo(xfo => xfo.Deny()); app.UseRedirectValidation(); |
Build your application, run your tests and then deploy them to your test system. If you rerun the check on securityheaders.com you now should get a B:
Check for errors
Your site may now be on a better rating, but it could as well be that some of those changes now produce tiny little errors that result in warnings inside the browser. We had one CSS file that was loaded over HTTP instead of HTTPS. Those errors are easy to fix, but you may need to visit your site and check that manually if you do not have a monitoring solution in place that does it for you.
Other low hanging fruits to pick
There are a few more little things you can do to improve the security of your application. Go back to the Startup.cs file and add this line to add a header for X-XSS-Protection
:
1 2 3 4 5 |
app.UseStaticFiles(); // Security - Registered after static files, for dynamic content. app.UseXXssProtection(options => options.EnabledWithBlockMode()); app.UseXfo(xfo => xfo.Deny()); |
Your users do not need to know which web server you use. To stop advertising your server you can open Program.cs and add this line in the BuildWebHost()
method:
1 2 3 4 |
WebHost.CreateDefaultBuilder(args) // keep your other configuration settings .UseKestrel(c => c.AddServerHeader = false) .Build(); |
APS.NET Core does not have a web.config
file anymore. However, certain headers can only be set there and if you create this file it will still be used. To remove the X-Powered-By
header and to add one for Feature-Policy
you can create this web.config
file:
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <httpProtocol> <customHeaders> <remove name="X-Powered-By" /> <add name="Feature-Policy" value="geolocation 'self'"/> </customHeaders> </httpProtocol> </system.webServer> </configuration> |
This will move your score to an A:
What about the Content-Security-Policy?
This final step is important, but it takes a lot to consider. Even with a small site like the one of the user group you have a lot of external services that need to be whitelisted. Before we attack this point, we want to improve our monitoring and consolidate the external services we use.
NWebsec for the Full Framework
If you want to use the benefits from NWebsec for the .Net Full Framework, you only need to change the package you install. You find the instructions in the ASP.Net 4 section of the documentation.
Instead of using the fluent configuration on the middleware you can put all the configuration inside the web.config
file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<system.webServer> <modules> <add name="NWebsecHttpHeaderSecurityModule" type="NWebsec.Modules.HttpHeaderSecurityModule, NWebsec" /> </modules> <httpProtocol> <customHeaders> <clear /> <add name="Feature-Policy" value="geolocation 'self'"/> <add name="Referrer-Policy" value="no-referrer"/> </customHeaders> </httpProtocol> <security> <requestFiltering> <hiddenSegments> <add segment="NWebsecConfig" /> </hiddenSegments> </requestFiltering> </security> </system.webServer> <nwebsec> <httpHeaderSecurityModule xmlns="http://nwebsec.com/HttpHeaderSecurityModuleConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="NWebsecConfig/HttpHeaderSecurityModuleConfig.xsd"> <redirectValidation enabled="true" /> <securityHttpHeaders> <x-Frame-Options policy="Deny"/> <strict-Transport-Security max-age="365" /> <x-Content-Type-Options enabled="true" /> <x-XSS-Protection policy="FilterEnabled" blockMode="true"/> </securityHttpHeaders> </httpHeaderSecurityModule> </nwebsec> </configuration> |
This has the same effect and will improve the score for your site as we did with the middleware for .Net Core.
Conclusion
Most of the changes to improve your score on the securityheaders.com checker can be done within a few minutes. That will not only give you a good feeling about the result, but it will improve the security for the users of your site as well. Try it!