10

Removing the IIS Server Request Header from ASP.NET Core Apps (any version)

 1 year ago
source link: https://weblog.west-wind.com/posts/2023/May/08/Removing-IIS-Server-Request-Header-from-ASPNET-Core-Apps-any-version
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Removing the IIS Server Request Header from ASP.NET Core Apps (any version)


Yesterday • from Maui, Hawaii   •   2 comments

Headless.jpg

If you're running an ASP.NET Core application on IIS, you have probably noticed that IIS injects a Server header into your HTTP headers that advertises the server platform, which is not always welcome.

Here's what that header looks like:

HttpHeaderswithIis.png

Now you might think it's easy: Slap on a Response.Headers.Remove("Server") and you're done, right? But no, that doesn't work with the IIS Server header because... well, it's different than other headers.

If you're running ASP.NET Core with Kestrel you also get a Server header, but it's a little different with Kestrel in that it generates its own Http header as part of the ASP.NET framework processing, while the IIS setting is generated by IIS's internal pipeline processing.

I'm posting this now, as there are a lot of older posts out there that provide solutions that no longer work. The web.config solution provided here works with any version of ASP.NET Core as long as you use IIS 10.

Why is the Server Header different?

Adding and removing headers in ASP.NET Core is kind of a hornet's nest, because there's no direct built-in way to do it globally for all requests in ASP.NET Core. I talked about how to do this using some custom middleware in a previous post, and one of the options of the middleware I discussed was the ability to remove headers from an outgoing HttpRepsonse request.

That's all fine and good, and this works great for most headers including manually added headers, framework injected headers (like cookies, CORS, etc.) and also for framework headers like the Kestrel Server header.

MarkdownMonster-Display.png

But the IIS Server header is different: It's not actually generated as part of the ASP.NET Core framework processing, but rather by IIS's internal pipeline and is injected by IIS very late in the Response processing.

Removing the IIS Server Header - in web.config

For this reason the reliable and most effective way to remove the Server header is to do it as part of the IIS processing configuration, in this case by using web.config and setting one of the requestFiltering options:

<system.webServer>
 <security>
    <requestFiltering removeServerHeader="true" />
 </security>
</system.webServer>

This feature only works in IIS 10 which was introduced with Windows 10 and Windows Server 2016.

This works great and it requires no other changes in your application. You'll just have to ensure that you publish your custom web.config that includes the above <security> section with your application.

Remember, if you publish an ASP.NET Core project it either uses the web.config that you provide as part of your project in the root folder or it creates one for you when you publish.

It's best to provide a web.config in your project:

webConfigInProject.png

Note that web.config is overwritten on any publish operation regardless of whether you provide one in your project or not, so be sure not to change the copy in the deployed application folder as it gets overwritten.

What doesn't work

I don't want to belabor the point, but since this issue has gone through a number of changes since earlier versions of ASP.NET Core, I want to take a moment and discuss some other approaches that don't work and why.

  • Removing headers via code in Middleware
    Although you can use middleware to add and remove headers, the Server header in IIS different in that it's added by IIS itself and is added very late in the IIS request processing pipeline. Therefore you can't remove it from ASP.NET code as far as I know.

  • Kestrel Hosting Configuration Options
    Several older Posts and StackOverflow posts point at using Kestrel configuration options to remove the Server header via the Builder configuration. While that works for Kestrel's Server header, it has no effect on when hosted in IIS.

Invariably most of the solutions rely on modifying the Kestrel Hosting configuration options, which looks something like this (in ASP.NET Core 6+):



csharp

var builder = WebApplication.CreateBuilder(args); builder.WebHost .UseKestrel(option => option.AddServerHeader = false); .UseIIS();

This does not work for the IIS header! It only works for the Kestrel header.

There are a couple of problems with this besides not removing the IIS Server header.

  • It's non-obvious and most places I found this omitted the .UseIIS() call, which means the app runs fine with Kestrel but bombs with IIS!

  • You're essentially overriding the base configuration for the Host(s) that occur in the default CreateBuilder() call so the configuration may not be as optimized as the defaults.

Websurge-Display.png

Summary

The moral of the story is: This is an IIS setting and you should use IIS to override it, so use the web.config setting...

Resources

this post created and published with the Markdown Monster Editor

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK