[security] Remove Server Response Header IIS7

Is there any way to remove "Server" response header from IIS7? There are some articles showing that using HttpModules we can achieve the same thing. This will be helpful if we don't have admin right to server. Also I don't want to write ISAPI filter.

I have admin rights to my server. So I don't want to do the above stuff. So, please help me to do the same.

This question is related to security iis-7 header response

The answer is


Add this to your global.asax.cs:

protected void Application_PreSendRequestHeaders()
{
    Response.Headers.Remove("Server");
    Response.Headers.Remove("X-AspNet-Version");
    Response.Headers.Remove("X-AspNetMvc-Version");
}

I had researched this and the URLRewrite method works well. Can't seem to find the change scripted anywhere well. I wrote this compatible with PowerShell v2 and above and tested it on IIS 7.5.

# Add Allowed Server Variable
    Add-WebConfiguration /system.webServer/rewrite/allowedServerVariables -atIndex 0 -value @{name="RESPONSE_SERVER"}
# Rule Name
    $ruleName = "Remove Server Response Header"
# Add outbound IIS Rewrite Rule
    Add-WebConfigurationProperty -pspath "iis:\" -filter "system.webServer/rewrite/outboundrules" -name "." -value @{name=$ruleName; stopProcessing='False'}
#Set Properties of newly created outbound rule 
    Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST"  -filter "system.webServer/rewrite/outboundRules/rule[@name='$ruleName']/match" -name "serverVariable" -value "RESPONSE_SERVER"
    Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST"  -filter "system.webServer/rewrite/outboundRules/rule[@name='$ruleName']/match" -name "pattern" -value ".*"
    Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST"  -filter "system.webServer/rewrite/outboundRules/rule[@name='$ruleName']/action" -name "type" -value "Rewrite"

Actually the coded modules and the Global.asax examples shown above only work for valid requests.

For example, add < on the end of your URL and you will get a "Bad request" page which still exposes the server header. A lot of developers overlook this.

The registry settings shown do not work either. URLScan is the ONLY way to remove the "server" header (at least in IIS 7.5).


Or add in web.config:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <remove name="X-AspNet-Version" />
            <remove name="X-AspNetMvc-Version" />
            <remove name="X-Powered-By" />
            <!-- <remove name="Server" />  this one doesn't work -->
        </customHeaders>
    </httpProtocol>
</system.webServer>

Following up on eddiegroves' answer, depending on the version of URLScan, you may instead prefer RemoveServerHeader=1 under [options].

I'm not sure in which version of URLScan this option was added, but it has been available in version 2.5 and later.


This web.config setup works to remove all unnecessary headers from the ASP.NET response (at least starting from IIS 10):

<system.web>
    <!-- Removes version headers from response -->
    <httpRuntime enableVersionHeader="false" />
</system.web>

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <!--Removes X-Powered-By header from response -->
            <clear />
        </customHeaders>
    </httpProtocol>

    <security>
        <!--Removes Server header from response-->
        <requestFiltering removeServerHeader ="true" />
    </security>
</system.webServer>

Please note that this hides all the headers for the "application", as do all the other approaches. If you e.g. reach some default page or an error page generated by the IIS itself or ASP.NET outside your application these rules won't apply. So ideally they should be on the root level in IIS and that sill may leave some error responses to the IIS itself.

P.S. There is a bug in IIS 10 that makes it sometimes show the server header even with correct config. It should be fixed by now, but IIS/Windows has to be updated.


I tried all of the stuff here and on several other similar stack overflow threads.

I got hung up for a bit because I forgot to clear my browser cache after making config changes. If you don't do that and the file is in your local cache, it will serve it back to you with the original headers (duh).

I got it mostly working by removing the runAllManagedModulesForAllRequests:

<modules runAllManagedModulesForAllRequests="true">

This removed the extraneous headers from most of the static files but I still was getting the "Server" header on some static files in my WebAPI project in swagger.

I finally found and applied this solution and now all of the unwanted headers are gone:

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

which discusses his code that is here:

https://github.com/Dionach/StripHeaders/releases/tag/v1.0.5

This is a Native-Code module. It is able to remove the Server header, not just blank out the value. By default it removes:

  • Server
  • X-Powered-By
  • X-Aspnet-Version
  • Server: Microsoft-HTTPAPI/2.0 -- which would be returned if "the request fails to be passed to IIS"

To remove the Server: header, go to Global.asax, find/create the Application_PreSendRequestHeaders event and add a line as follows (thanks to BK and this blog this will also not fail on the Cassini / local dev):

protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
{
    // Remove the "Server" HTTP Header from response
    HttpApplication app = sender as HttpApplication;
    if (null != app && null != app.Request && !app.Request.IsLocal &&
        null != app.Context && null != app.Context.Response)
    {
        NameValueCollection headers = app.Context.Response.Headers;
        if (null != headers)
        {
            headers.Remove("Server");
        }
    }
}

If you want a complete solution to remove all related headers on Azure/IIS7 and also works with Cassini, see this link, which shows the best way to disable these headers without using HttpModules or URLScan.


You can add below code in Global.asax.cs file

    protected void Application_PreSendRequestHeaders()
    {
        Response.Headers.Remove("Server");
    }

UrlScan can also remove the server header by using AlternateServerName= under [options].


Addition to the URL Rewrite answer, here is the complete XML for web.config

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

URL Rewrite


Try setting the HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\DisableServerHeader registry entry to a REG_DWORD of 1.


I found an article that explains why we need to do both Registry edit and use a tool such as UrlScan to set this up in IIS properly. I followed it on our servers and it works: http://blogs.msdn.com/b/varunm/archive/2013/04/23/remove-unwanted-http-response-headers.aspx. If you only use UrlScan but don't do the registry change, during the time you are stopping World Wide Publishing Service, your server will return server http response from the HTTP.sys file. Also, here are common pitfals of using UrlScan tool: http://msdn.microsoft.com/en-us/library/ff648552.aspx#ht_urlscan_008


IIS 7.5 and possibly newer versions have the header text stored in iiscore.dll

Using a hex editor, find the string and the word "Server" 53 65 72 76 65 72 after it and replace those with null bytes. In IIS 7.5 it looks like this:

4D 69 63 72 6F 73 6F 66 74 2D 49 49 53 2F 37 2E 35 00 00 00 53 65 72 76 65 72 

Unlike some other methods this does not result in a performance penalty. The header is also removed from all requests, even internal errors.


If you just want to remove the header you can use a shortened version of lukiffer's answer:

using System.Web;

namespace Site
{
    public sealed class HideServerHeaderModule : IHttpModule
    {
        public void Dispose() { }

        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders +=
            (sender, e) => HttpContext.Current.Response.Headers.Remove("Server");
        }
    }
}

And then in Web.config:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="CustomHeaderModule" type="Site.HideServerHeaderModule" />
  </modules>
</system.webServer>

Scott Mitchell provides in a blog post solutions for removing unnecessary headers.

As already said here in other answers, for the Server header, there is the http module solution, or a web.config solution for IIS 10+, or you can use URLRewrite instead for blanking it.

The most practical solution for an up-to-date (IIS 10 +) setup is using removeServerHeader in the web.config:

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

For X-AspNet-Version and X-AspNetMvc-Version, he provides a better way than removing them on each response: simply not generating them at all.

Use enableVersionHeader for disabling X-AspNet-Version, in web.config

<system.web>
  ...
  <httpRuntime enableVersionHeader="false" />
  ...
</system.web>

Use MvcHandler.DisableMvcResponseHeader in .Net Application_Start event for disabling X-AspNetMvc-Version

MvcHandler.DisableMvcResponseHeader = true;

And finally, remove in IIS configuration the X-Powered-By custom header in web.config.

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

Beware, if you have ARR (Application Request Routing), it will also add its own X-Powered-By, which will not be removed by custom headers settings. This one has to be removed through the IIS Manager, Editor configuration on the IIS root (not on a site): go to system.webServer/proxy node and set arrResponseHeader to false. After an IISReset, it is taken into account.
(I have found this one here, excepted this post is about old IIS 6.0 way of configuring things.)

Do not forget that solution by application code does not apply by default to header generated on static content (you may activate the runAllManagedModulesForAllRequests for changing that, but it causes all requests to run .Net pipeline). It is not an issue for X-AspNetMvc-Version since it is not added on static content (at least if static request are not run in .Net pipeline).

Side note: when the aim is to cloak used technology, you should also change standard .Net cookie names (.ASPXAUTH if forms auth activated (use name attribute on forms tag in web.config), ASP.NET_SessionId (use <sessionState cookieName="yourName" /> in web.config under system.web tag), __RequestVerificationToken (change it by code with AntiForgeryConfig.CookieName, but unfortunately does not apply to the hidden input this system generates in the html)).


With the URL Rewrite Module Version 2.0 for IIS (UrlRewrite) enabled, in the configuration section <configuration> ? <system.webServer> ? <rewrite> add the outbound rule:

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

In IIS 10, we use a similar solution to Drew's approach, i.e.:

using System;
using System.Web;

namespace Common.Web.Modules.Http
{
    /// <summary>
    /// Sets custom headers in all requests (e.g. "Server" header) or simply remove some.
    /// </summary>
    public class CustomHeaderModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders += OnPreSendRequestHeaders;
        }

        public void Dispose() { }

        /// <summary>
        /// Event handler that implements the desired behavior for the PreSendRequestHeaders event,
        /// that occurs just before ASP.NET sends HTTP headers to the client.
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnPreSendRequestHeaders(object sender, EventArgs e)
        {
            //HttpContext.Current.Response.Headers.Remove("Server");
            HttpContext.Current.Response.Headers.Set("Server", "MyServer");
        }
    }
}

And obviously add a reference to that dll in your project(s) and also the module in the config(s) you want:

_x000D_
_x000D_
<system.webServer>_x000D_
    <modules>_x000D_
      <!--Use http module to remove/customize IIS "Server" header-->_x000D_
      <add name="CustomHeaderModule" type="Common.Web.Modules.Http.CustomHeaderModule" />_x000D_
    </modules>_x000D_
</system.webServer>
_x000D_
_x000D_
_x000D_

IMPORTANT NOTE1: This solution needs an application pool set as integrated;

IMPORTANT NOTE2: All responses within the web app will be affected by this (css and js included);


The solution proposed above in combination worked for me with following changes. Here I am posting my scenario and solution.

For me I wanted to remove the following headers:

  • Server
  • X-Powered-By
  • X-AspNet-Version
  • X-AspNetMvc-Version

I added these to my global.asax:

<%@ Application Language="C#" %>
<script runat="server">
    protected void Application_PreSendRequestHeaders()
    {
        Response.Headers.Remove("Server");
        Response.Headers.Remove("X-Powered-By");
        Response.Headers.Remove("X-AspNet-Version");
        Response.Headers.Remove("X-AspNetMvc-Version");
    }
</script>

The above event was not getting triggered, so for that I added following to web.config then it worked.

<modules runAllManagedModulesForAllRequests="true" />

and for removing version header I also added following to web.config:

<httpRuntime enableVersionHeader="false" />

Changes in web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
    </system.webServer>
    <system.web>
        <httpRuntime enableVersionHeader="false" />
    </system.web>
</configuration>

Hope it helps!


In IIS7 you have to use an HTTP module. Build the following as a class library in VS:

namespace StrongNamespace.HttpModules
{
  public class CustomHeaderModule : IHttpModule
  { 
    public void Init(HttpApplication context)
    {
      context.PreSendRequestHeaders += OnPreSendRequestHeaders;
    } 

    public void Dispose() { } 

    void OnPreSendRequestHeaders(object sender, EventArgs e)
    {
      HttpContext.Current.Response.Headers.Set("Server", "Box of Bolts");
    }
  }
}

Then add the following to your web.config, or you configure it within IIS (if you configure within IIS, the assembly must be in the GAC).

<configuration>
  <system.webServer>
    <modules>
      <add name="CustomHeaderModule"
       type="StrongNamespace.HttpModules.CustomHeaderModule" />
    </modules>
  </system.webServer>
</configuration>

Examples related to security

Monitoring the Full Disclosure mailinglist Two Page Login with Spring Security 3.2.x How to prevent a browser from storing passwords JWT authentication for ASP.NET Web API How to use a client certificate to authenticate and authorize in a Web API Disable-web-security in Chrome 48+ When you use 'badidea' or 'thisisunsafe' to bypass a Chrome certificate/HSTS error, does it only apply for the current site? How does Content Security Policy (CSP) work? How to prevent Screen Capture in Android Default SecurityProtocol in .NET 4.5

Examples related to iis-7

Accessing a local website from another computer inside the local network in IIS 7 500.21 Bad module "ManagedPipelineHandler" in its module list HTTP Error 503. The service is unavailable. App pool stops on accessing website IIS - 401.3 - Unauthorized 500.19 - Internal Server Error - The requested page cannot be accessed because the related configuration data for the page is invalid ASP.NET Web API application gives 404 when deployed at IIS 7 WebApi's {"message":"an error has occurred"} on IIS7, not in IIS Express enabling cross-origin resource sharing on IIS7 How to fix 'Microsoft Excel cannot open or save any more documents' IIS 7, HttpHandler and HTTP Error 500.21 No 'Access-Control-Allow-Origin' header in Angular 2 app How to add header row to a pandas DataFrame How can I make sticky headers in RecyclerView? (Without external lib) Adding header to all request with Retrofit 2 Python Pandas Replacing Header with Top Row Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers Pythonically add header to a csv file fatal error C1010 - "stdafx.h" in Visual Studio how can this be corrected? correct PHP headers for pdf file download How to fix a header on scroll

Examples related to response

Returning JSON object as response in Spring Boot Guzzlehttp - How get the body of a response from Guzzle 6? Keep getting No 'Access-Control-Allow-Origin' error with XMLHttpRequest Express.js Response Timeout What is the difference between response.sendRedirect() and request.getRequestDispatcher().forward(request,response) Return generated pdf using spring MVC Create HTTP post request and receive response using C# console application java.lang.IllegalStateException: Cannot (forward | sendRedirect | create session) after response has been committed C# Encoding a text string with line breaks Remove Server Response Header IIS7