36

As part of an effort to make our API and site more secure, I'm removing headers that leak information about what the site is running.

Example before stripping headers:

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 05 Jun 2013 00:27:54 GMT
Content-Length: 3687

Web.config:

<httpProtocol>
  <customHeaders>
    <remove name="X-Powered-By" />
  </customHeaders>
</httpProtocol>

Global.asax.cs:

protected void Application_PreSendRequestHeaders() {
    Response.Headers.Remove("Server");
    Response.Headers.Remove("X-AspNet-Version");
    Response.Headers.Remove("X-AspNetMvc-Version");
    Response.AddHeader("Strict-Transport-Security", "max-age=300");
    Response.AddHeader("X-Frame-Options", "SAMEORIGIN");
}

And after that, all calls to the site and API return safer headers, like so:

HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/html; charset=utf-8
Date: Wed, 05 Jun 2013 00:27:54 GMT
Content-Length: 3687

So far, so good. However, I've noticed in Firebug that if you look at static content (loading.gif, for example), it still includes the server header.

HTTP/1.1 304 Not Modified
Cache-Control: no-cache
Accept-Ranges: bytes
Etag: "a3f2a35bdf45ce1:0"
Server: Microsoft-IIS/8.0
Date: Tue, 25 Jun 2013 18:33:16 GMT

I'm assuming this is being handled by IIS somehow, but can't find anywhere to remove that header. I've tried adding:

<remove name="Server" /> 

to the httpProtocol/customHeaders section in Web.config, as mentioned above. I've also tried going into the IIS Manager's HTTP Response Headers section and adding a fake name/value pair for the Server header. In both cases, it still returns

Server: Microsoft-IIS/8.0

when loading any images, CSS, or JS. Where/what do I need to set something to fix this?

casperOne
  • 73,706
  • 19
  • 184
  • 253
Chris Doggett
  • 19,959
  • 4
  • 61
  • 86

5 Answers5

18

The only one without an easy listed solution for was the "Server" header. I was able to remove it locally in IIS and in an Azure web site by adding this in the web.config

<system.webServer>
  <security>
    <requestFiltering removeServerHeader="true" />
  </security>
</system.webServer>
dimension314
  • 212
  • 3
  • 6
  • 4
    Unfortunately, this only works in IIS 10.0+, and the OP stated in the question title that his situation involved IIS 7/8. – Alexandre May 22 '19 at 15:15
12

The same way that's in this answer, and in this website:, you should use the following steps:

C#:

namespace MvcExtensions.Infrastructure
{
    public class CustomServerName : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders += OnPreSendRequestHeaders;
        }

        public void Dispose() { }

        void OnPreSendRequestHeaders(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Headers.Remove("Server");
        }
    }
}

Web.config:

<system.webServer>
   <modules>
      <add name="CustomHeaderModule" type="MvcExtensions.Infrastructure.CustomServerName" />
   </modules>
</system.webServer>
Community
  • 1
  • 1
Gabriel
  • 887
  • 10
  • 22
  • I may have misunderstood things, but this MS site https://learn.microsoft.com/en-us/aspnet/aspnet/overview/web-development-best-practices/what-not-to-do-in-aspnet-and-what-to-do-instead#presend warns about using the `PreSendRequest` event. Therefore, I think @hexpoint 's answer is better (I just tested and it worked like a charm) https://stackoverflow.com/a/49457128/3569421 – carlosrafaelgn Nov 18 '18 at 19:56
  • 1
    * The only drawback, is that @hexpoint 's answer does not work on IIS 7.5, only on IIS 10 + – carlosrafaelgn Nov 18 '18 at 20:03
10

You should be able to force all requests to go through your managed code by adding this to your webconfig:

<modules runAllManagedModulesForAllRequests="true">

Then, even static files should adhere to your header rules.

Bill Gregg
  • 7,067
  • 2
  • 22
  • 39
  • Thanks, that worked beautifully. In general, is there much to worry about in terms of speed doing it that way? For our app/API, it's a very limited audience, things are cached, and the queries take the lion's share of response size/time, so I'm not really worried. Just good to know. – Chris Doggett Jun 25 '13 at 19:00
  • 1
    Spinning up the entire ASP.Net stack to serve static files is going to be more resource intensive, which is why it is not done by default. But based on your situation, it seems like the cost is worth the benefit. – Bill Gregg Jun 25 '13 at 19:02
  • This response to another question (http://stackoverflow.com/a/12615970/64203) actually wound up not needing to hit the full stack, so I wound up going with it for my final solution, but thanks again for the help. – Chris Doggett Jun 25 '13 at 21:00
  • 4
    You should not use that. It's a waste of resources: http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html – Gabriel Dec 02 '13 at 18:37
  • 1
    This has no effect on static files / 304 responses. I have done all these steps, but when a browser requests a static file and server returns 304 Not Modified, "Server" header is still there. – Jano Jul 11 '14 at 01:53
  • This doesn't work for virtual directories being served from IIS without an associated ASP.Net application. – grrizzly Sep 22 '14 at 17:46
  • @Jano Ha! your comment just clued me in on my issue--you can make changes to fix everything correctly, but if the content is still in your local cache, it still serves up the old headers to the browser. Flush browser cache and test again and it works fine now. Yay! – TechSavvySam Feb 20 '18 at 20:31
9

Unfortunately managed code modules only work for code passing through the ASP.NET pipeline, whilst others have correctly suggested it is possible to force all requests through managed code, I personally feel this is less than desirable.

In order to remove headers from all requests, including static content, which by default is served directly and not through managed code, it is possible to use a Native-Code module. Unfortunately Native-Code modules are a little more difficult to write as they use the win32 APIs rather than ASP.NET, however in my experience they are much more suitable to removing headers.

The following link has binaries and source code for a Native-Code module that can be used to remove headers. It requires no extra configuration to remove the "Server" headers, but other headers to remove can be added in the IIS configuration.

http://www.dionach.com/blog/easily-remove-unwanted-http-headers-in-iis-70-to-85

ph1ll
  • 421
  • 3
  • 8
  • 1
    Not sure why this was voted down. This looks like a fairly strong answer. +1 – Jeremy A. West Jan 13 '15 at 16:45
  • "Suggested edit queue is full" -- Link's dead, here's a wayback machine version: https://web.archive.org/web/20160618210927/https://www.dionach.com/blog/easily-remove-unwanted-http-headers-in-iis-70-to-85 and here's the Github page for the module by Dionach: https://github.com/Dionach/StripHeaders – Lovethenakedgun Nov 24 '21 at 10:06
6

Use the IIS UrlRewrite 2.0 for blanking the Server response header. Add following code in the Web.config file

 <system.webServer>
<rewrite>
<outboundRules>
<rule name="Remove RESPONSE_Server" >
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>

https://stackoverflow.com/a/12615970/5810078

Community
  • 1
  • 1
Aathira
  • 655
  • 3
  • 14
  • 31
  • 1
    Thank you for this concise and correct answer. The internet is packed with people providing the wrong answer for this or just telling you not to worry about leaking the server version. – theycallmemorty Oct 16 '20 at 17:03
  • This sorted the problem for me on Microsoft-IIS/10.0 – Edo Oct 13 '21 at 11:03