Scott Hanselman

Easily adding Security Headers to your ASP.NET Core web app and getting an A grade

March 24, 2020 Comment on this post [17] Posted in ASP.NET | Linux
Sponsored By

Well that sucks.

Score of F on SecurityHeaders.com

That's my podcast website with an F rating from SecurityHeaders.com. What's the deal? I took care of this months ago!

Turns out, recently I moved from Windows to Linux on Azure.

If I am using IIS on Windows, I can (and did) make a section in my web.config that looks something like this.

Do note that I've added a few custom things and you'll want to make sure you DON'T just copy paste this. Make yours, yours.

Note that I've whitelisted a bunch of domains to make sure my site works. Also note that I have a number of "unsafe-inlines" that are not idea.

<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>
...

But, if I'm NOT using IIS - meaning I'm running my ASP.NET app in a container or on Linux - this will be ignored. Since I recently moved to Linux, I assumed (my bad for no tests here) that it would just work.

My site is hosted on Azure App Service for Linux, so I want these headers to be output the same way. There are several great choices in the form of Open Source NuGet libraries to help. If I use the ASP.NET Core middleware pipeline then these headers will be output and work the SAME on both Windows AND Linux.

I'll be using the NWebsec Security Libraries for ASP.NET Core. They offer a simple fluent way to add the headers I want.

TO BE CLEAR: Yes I, or you, can add these headers manually with AddHeader but these simple libraries ensure that our commas and semicolons are correct. They also offer a strongly typed middleware that is fast and easy to use.

Taking the same web.config above and translating it to Startup.cs's Configure Pipeline with NWebSec looks 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("www.google.com","platform.twitter.com","cdn.syndication.twimg.com","fonts.googleapis.com")
.UnsafeInline()
)
.ScriptSources(s => s.Self()
.CustomSources("www.google.com","cse.google.com","cdn.syndication.twimg.com","platform.twitter.com" ... )
.UnsafeInline()
.UnsafeEval()
)
);

There is one experimental HTTP header that NWebSec doesn't support (yet) called Feature-Policy. It's a way that your website can declare at the server-side "my site doesn't allow use of the webcam." That would prevent a bad guy from injecting local script that uses the webcam, or some other client-side feature.

I'll do it manually both to make the point that I can, but also that you aren't limited by your security library of choice.

NOTE: Another great security library is Andrew Lock's NetEscapades that includes Feature-Policy as well as some other great features.

Here's my single Middleware that just adds the Feature-Policy header to all responses.

//Feature-Policy
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Feature-Policy", "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';");
await next.Invoke();
});

Now I'll commit, build, and deploy (all automatic for me using Azure DevOps) and scan the site again:

Score of A on SecurityHeaders.com

That was pretty straightforward and took less than an hour. Your mileage may vary but that's the general idea!


Sponsor: Protect your apps from reverse engineering and tampering with PreEmptive, makers of Dotfuscator. Dotfuscator has been in-the-box with Microsoft Visual Studio since 2003. Mention HANSELMAN for savings on a professional license!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
March 24, 2020 10:25
Unsafe eval and unsafe inline might not be the best options for a CSP Policy. Might be worth linking somewhere so people can see what all the values mean rather than copy pasting what you have here?
March 24, 2020 12:13
I scanned a few websites, some big (Microsoft, Google, Gmail, Bank of America, Hotmail.com, Yahoo.com, Facebook). Only facebook, yahoo and gmail got As. The rest got Ds. I thought that was interesting. I scanned yours as well (this site) and yours is just as or actually more secure now than theirs.
March 24, 2020 13:38
When you add such constraints as part of your HTTP headers or in the META tags in the web page itself, you are basically telling people how exactly they can craft malicious attacks using your websites. For example, now that someone knows what domains you trust for scripts, an attacker could use a DNS spoofing/poisoning + man-in-the-middle with malicious scripts that appear to be from that domain and use it to do really bad things to your visitors. Because of this, adding such headers is not really secure. If anything, it is "anti-secure". Comments?
March 24, 2020 13:47
And for those of you on .NET full fat you're sod out of luck and have to completely roll your own. All the nuGet packages relating to this are .NET core now (if they ever supported full fat .NET) and those that aren't haven been updated in years and are not very popular which leads me to have little trust in them. We do have our own IIS HttpSecurityHeader module so it's built into our site as opposed to relying on IIS. [SCOTT] Question for you. Can you find out why IIS insists on adding headers by default to websites that will cause a failure in penetration tests? Such as powered by IIS and the like? Worse than that these can't be overridden in the above module, :/
March 24, 2020 14:56
@Sujay Sarma - I respectfully disagree. You are correct that adding these headers tells an attacker which scripts on an external site to attack in order to get malicious code onto your site. But that doesn't mean it's a bad idea, particularly as part of a defense in depth strategy. (Even as a standalone, simply parsing the page source would yield the same information.) There's another tool, subresource integrity (SRI), in which you add an "integrity" attribute containing a checksum to any script tag which references an external site. That way if the external script is modified in any way, the checksum won't match and the browser can block it. According to Mozilla's SRI documentation it's supported everywhere except Edge, IE (no longer, IMHO, a modern browser anyhow) and Opera mobile. I couldn't find where Scott has written anything about this yet, but Scott Helme (founder of SecurityHeaders.com) has a nice write-up of SRI on his blog. (Combine that with the aforementioned Mozilla documentation and you can do this manually pretty easily.)
March 24, 2020 15:53
I checked your site on https://headerinspector.com, and you have a great score there too... But there's a few other items worth checking into, like fully configuring HSTS, and some legacy browser headers
March 24, 2020 16:39
@Sujay Sarma: These headers are not designed to address MITM attacks. These defend against script injections and XSS attacks. Public Key Pinning could be used against MITM attacks, but that's been deprecated. @That Blair Guy: SRI is pretty awesome. There used to be a require-sri-for directive in CSP, but that's been deprecated, too.
March 26, 2020 21:22
Peter - Um, no you don't, I literally included the IIS settings right there. I had a A grade with full framework and IIS.
March 28, 2020 9:24
I use nginx as reverse proxy and it automatically sets security headers, when used with 'Lets encrypt' Certbot.
March 29, 2020 0:33
I discovered that NWebsec also does a few other handy things beyond setting HTTP headers, like performing redirect validation.
March 30, 2020 10:02
Hey thanks admin for sharing this great article on your blog. I hope that it will work for me when I came to your website from search engine
March 30, 2020 11:09
@Sujay Sarma. The header doesn't tell the browser what sites _you_ trust. It instructs the browser to only load remote content from those sites. Comparing that with no header: load whatever you want. Also if you are server on https and you don't allow downgrade to http of linked resources, then the weaknesses become constrained to "google.com gets hacked to server malicious code" or "someone manages to issue a trusted certificate for google.com". I agree it's not perfect but it's all about minimising exploit surface area. If i managed to embed some html in this comment that linked to malicious JS, the browser would not load it.
March 31, 2020 13:39
Заходите к нам в магазин и купайте сумочки, рюкзаки, косметички по самой низкой цене и с беспалтной доставкой [url=https://ukrion.com.ua/]ukrion.com.ua[/url]! купит топ качество сумки в интернете Когда речь идет о стиле нельзя пренебрегать Хаксессуарами. Они расставляют акценты, тем самым помогая создать уместный гармоничный образ. При этом особо тщательно следует отнестись к выбору рюкзака. Ведь она может не только довершить ансамбль, но и полностью испортить его. Поэтому, каждая девушка должна знать, как выбрать и где купить сумку, чтобы она помогла создать не один стильный образ. Если нужна кожаная сумка, купить её не составит труда. Слева есть блок критериев, которые помогут вам выбрать аксессуар. Вам всего лишь необходимо задать тип, материал и цвет изделия, а система в свою очередь предложит вам подходящие варианты. Также, не забудьте указать пол. Если вы точно знаете, чего хотите - вы можете воспользоваться поиском. Все, что от вас требуется - ввести ключевые слова, которые характеризуют конкретный вариант. Например, купить у нас топ качество сумки или купить у нас сумку. [url=https://ukrion.com.ua/katalog]Интернет магазин сумок, кошельков, рюкзаков с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/ryukzaki]Купить Рюкзак с Бесплатной доставкой по Украине Рюкзак недорого[/url] [url=https://ukrion.com.ua/katalog/koshelki-kosmetichki]Купить Кошелек с Бесплатной доставкой по Украине Женский кошелек недорого[/url] [url=https://ukrion.com.ua/katalog/melkaya-galantereya]Купить мелкую галантерею с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki]Купить Сумки с Бесплатной доставкой по Украине Сумки недорого[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-kozhanye-sumki]Купить натуральные кожаные сумки с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-tekstilnye-sumki]Купить текстильную сумку с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-steganye-sumki]Купить стеганые сумку с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-kombinirovannye-sumki]Купить комбинированные сумки с Бесплатной доставкой по Украине[/url]
March 31, 2020 13:56
Заходите к нам в магазин и купайте сумочки, рюкзаки, косметички по самой низкой цене и с беспалтной доставкой [url=https://ukrion.com.ua/]ukrion.com.ua[/url]! купить у нас сумку в интернете Когда речь идет о стиле нельзя пренебрегать Хаксессуарами. Они расставляют акценты, тем самым помогая создать уместный гармоничный ваш образ. При этом особо тщательно следует отнестись к выбору косметички. Ведь она может не только довершить ансамбль, но и полностью испортить его. Поэтому, каждая девушка должна знать, как выбрать и где купить сумку, чтобы она помогла создать не один стильный образ. Если нужна сумка, купить её не составит труда. Слева есть блок критериев, которые помогут вам выбрать аксессуар. Вам всего лишь необходимо задать тип, материал и цвет изделия, а система в свою очередь предложит вам подходящие варианты. Также, не забудьте указать пол. Если вы точно знаете, чего хотите - вы можете воспользоваться поиском. Все, что от вас требуется - ввести ключевые слова, которые характеризуют конкретный вариант. Например, Как купить рюкзак или Сколько стоит купить рюкзак. [url=https://ukrion.com.ua/katalog]Интернет магазин сумок, кошельков, рюкзаков с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/ryukzaki]Купить Рюкзак с Бесплатной доставкой по Украине Рюкзак недорого[/url] [url=https://ukrion.com.ua/katalog/koshelki-kosmetichki]Купить Кошелек с Бесплатной доставкой по Украине Женский кошелек недорого[/url] [url=https://ukrion.com.ua/katalog/melkaya-galantereya]Купить мелкую галантерею с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki]Купить Сумки с Бесплатной доставкой по Украине Сумки недорого[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-kozhanye-sumki]Купить натуральные кожаные сумки с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-tekstilnye-sumki]Купить текстильную сумку с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-steganye-sumki]Купить стеганые сумку с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-kombinirovannye-sumki]Купить комбинированные сумки с Бесплатной доставкой по Украине[/url]
March 31, 2020 13:56
Be sure to test your website’s functionality After these changes - they can be breaking depending how your pages are built, what script resources you use etc.
March 31, 2020 14:11
Заходите к нам в магазин и купайте сумочки, рюкзаки, косметички по самой низкой цене и с беспалтной доставкой [url=https://ukrion.com.ua/]ukrion.com.ua[/url]! Как купить топ качество сумки в интернете Когда речь идет о стиле нельзя пренебрегать Хаксессуарами. Они расставляют акценты, тем самым помогая создать уместный гармоничный образ. При этом особо тщательно следует отнестись к выбору кожаной сумки. Ведь она может не только довершить ансамбль, но и полностью испортить его. Поэтому, каждая девушка должна знать, как выбрать и где купить сумку, чтобы она помогла создать не один стильный образ. Если нужна рюкзак, купить её не составит труда. Слева есть блок критериев, которые помогут вам выбрать аксессуар. Вам всего лишь необходимо задать тип, материал и цвет изделия, а система в свою очередь предложит вам подходящие варианты. Также, не забудьте указать пол. Если вы точно знаете, чего хотите - вы можете воспользоваться поиском. Все, что от вас требуется - ввести ключевые слова, которые характеризуют конкретный вариант. Например, купить у нас кошелек или цена сумку. [url=https://ukrion.com.ua/katalog]Интернет магазин сумок, кошельков, рюкзаков с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/ryukzaki]Купить Рюкзак с Бесплатной доставкой по Украине Рюкзак недорого[/url] [url=https://ukrion.com.ua/katalog/koshelki-kosmetichki]Купить Кошелек с Бесплатной доставкой по Украине Женский кошелек недорого[/url] [url=https://ukrion.com.ua/katalog/melkaya-galantereya]Купить мелкую галантерею с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki]Купить Сумки с Бесплатной доставкой по Украине Сумки недорого[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-kozhanye-sumki]Купить натуральные кожаные сумки с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-tekstilnye-sumki]Купить текстильную сумку с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-steganye-sumki]Купить стеганые сумку с Бесплатной доставкой по Украине[/url] [url=https://ukrion.com.ua/katalog/sumki/zhenskie-kombinirovannye-sumki]Купить комбинированные сумки с Бесплатной доставкой по Украине[/url]
April 01, 2020 16:44
That's a really great tool. I have used it on my website and it works like magic.

(will show your gravatar icon)
5-3=?
Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, li, ol, pre, strike, strong, sub, super, u, ul) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Live Comment Preview

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.