A massively updated version of this post is over here.

This page is a collection of instructions to remove unnecessary server headers which may be reported as part of a Penetration Test performed by a security engineer or reported via automated tools. I have catalogued these remediation instructions for many technologies in one place to save the vast amounts of searching required for some of the more obscure technologies. Each section below is be divided into a short solution and along with a longer one. The “Short Answer” gives the quick means to remove the offending header while the “Long Answer” gives more details along with alternate and (perhaps) more thorough solutions. This page is periodically updated (though the timestamp may not change).

Why bother? In general, excessive headers are bad:

  • They expose what version of software is running on the server, reducing the work an attacker needs to do before trying to attack the system.
  • Headers are the same for a normal user or an attacker. So, a known long string of characters in an encrypted data stream might aid an attacker in cracking open the encrypted TLS connection of another user.
  • It’s a general waste of bandwidth and processing power.

The solution for many headers is presented here. If you have other headers that keep popping up and would like them documented on this blog, pass them along to me to publishing.

Unixy

Server: Apache/2.2.x …

Short Answer

Set these in httpd.conf:

Long Answer

Apache’s Server header ranges from the ultra detailed ‘Server: Apache/2.2.15 (CentOS) DAV/2 PHP/5.3.3 mod_ssl/2.2.15 OpenSSL/1.0.1e-fips Phusion_Passenger/4.0.59 mod_perl/2.0.4 Perl/v5.10.1’ to the simplistic ‘Server: Apache’. It is best to use the minimal version. To configure, add this to httpd.conf or equivalent file:

These two options will reduce the Apache identification to just “Apache” with no version indicators. Both work for Apache 1.x and 2.x.

To fully remove the header, one option is to modify the code and compile the server to completely remove the server header. This is a bad idea as your organization will now have the added responsibility of patching the code each time there is a security update. It is best to rely on your Apache vendor’s packages for your patch management.

Another full-removal mechanism is to use mod_security’s SecServerSignature to modify the Server header value value with something like:

A third option is to use mod_headers and modify the Server header directly in httpd.conf with something like:

However, it should be noted that the fact Apache is used can be ascertained via other means and fingerprinting techniques. For example, Apache sets the Date header in a different spot in the HTTP header list than IIS will send it. There are also various TCP handshake tricks that can be done to determine the Operating System (e.g., IIS on Linux will tip off a determined attacker). The fact that a system uses PHP probably means that Apache or nginx are being used anyway. So, removing the Server header completely via the complex means above is not worth the trouble.

Server: nginx/1.8.x

Short Answer

In nginx.conf, add this line:

Long Answer

Edit the nginx.conf configuration file add a server_tokens off line in the top level of the file:

Like Apache, setting server_tokens off will remove the version of nginx but not that fact that nginx is being used. To further remove the header, it is possible to re-compile the code with a new header.

Another option is to use a module called “ngx_headers_more”. This nginx add-on allows for more control over the Server header. So, to delete the Server header, add this to the nginx.conf:

Or even set a custom server header, like so:

Be sure to dynamically load the module or to re-compile the server as required per the version of nginx.

X-Powered-By: PHP/5.x.x …

Short Answer

Add or modify the php.ini to set the expose_php variable to off, like so:

Long Answer

PHP headers give away the version, patch level, and more in something like ‘X-Powered-By: PHP/5.1.6-3+b2’. It is best to remove this exposure by changing the php.ini configuration to shut this off. So, modify the php.ini file and set the ‘expose_php’ variable to off like this:

Another option is to use Apache’s mod_headers to disable the header with something like:

The principle of “Defense in Depth” might mean you do both, just in case someone forgets to disable the variable on a server, but in general, modification of the variable is sufficient.

Java-ish & JavaScripty

X-Powered-By: Servlet/3.0 (WebSphere 8.5.x and others)

Short Answer

Set the com.ibm.ws.webcontainer.disablexPoweredBy property to true.

Long Answer

The best solution is to set the com.ibm.ws.webcontainer.disablexPoweredBy property to true. It is possible to modify X-Powered-By via the com.ibm.ws.webcontainer.xPoweredBy to a value such as ‘PHP/5.1.6-3+b2’. But, this is not recommended – just disable it.

Another option, if using the IBM HTTPd Server along with WebSphere, is to configure the server to unset the X-Powered-By header via mod_headers. Since IBM HTTPd Server is really Apache, use the same technique as shown above with Apache, mod_headers, and PHP:

$WSEP (WebSphere proxy request)

Short Answer

Add this property to server.xml:

Long Answer

The $WSEP header is generally produced when the WebSphere Application Server is performing some type of proxying action during a request or response. However, we have observed it in situations where the server owner was not aware of any proxy configuration. To disable the appearance of the header, add this property to server.xml:

X-Powered-By: Express

Short Answer

For Express 3.0 or newer:

However, for a more thorough (and highly recommended) solution, just use Helmet instead:

Long Answer

In Express 3.0 or newer, there are two means:

For older versions of Express, you need to write middleware that removes the header:

However, the Helmet security package can both remove this header and enable many other security features, such as clickjack prevention, some XSS protection, secure caching controls, etc. All by adding this:

For more information on Helmet, see https://www.npmjs.com/package/helmet.

X-Powered-By: Node* with nginx

Short Answer

For a server where Node proxies through nginx, update the proxy settings in nginx.conf with:

Server: Glassfish & X-Powered-By: Servlet/3.0 JSP/2.2

Short Answer

For the Server header, add a ‘product.name’ flag to the JVM options or command line:

For X-Powered-By, add this to web.xml:

Long Answer

A detailed explanation of the above is provided on the Bistro 2.0! blog (new URL, sigh, Oracle blogs.oracle.com).

X-Powered-By: Servlet 2.x; JBoss-4.x / JBoss-5.x

Short Answer

Edit web.xml and remove the <context-param> setting for “X-Powered-By”. Basically, delete this:

Server: Jetty(9.x.x…)

Short Answer

To remove Jetty 9.x’s Server header while running in standalone mode, add this to start.ini:

Server: Jetty 8.x & 7.x

Short Answer

To remove Jetty 8.x’s or 7.x’s Server header while running in embedded mode, instantiate the server with the follow lines of code:

The solution is a little more verbose when running Jetty in standalone mode. The following is to be added to jetty.xml and this code should disable the Jetty header. However, this configuration has not been tested by me, it is theoretical (someone confirm and get back to me).

Nevertheless, if you’re using Jetty 8.x, it is end of life and you should consider upgrading to Jetty 9.x or newer.

X-Powered-By: JSF/1.2 — Mojarra and others

Short Answer

To remove X-Powered-By in JSF applications, add this to web.xml:

Load Balancer / Firewall / WAF / Weirdness

Server: BigIP

Short Answer

Add noserver to the rule:

Long Answer

Generally, we see this when the server is doing a redirect from HTTP to HTTPS and in no other requests. So, adjust the redirect rule by adding noserver where appropriate. For example:

Microsofty

At the bottom of this section, there is a combined configuration to correct all of the exposed Microsoft headers presented here.

Microsoft-IIS/x.x

Short Answer for IIS hosted on Azure’s cloud

For Azure, add this to the configuration:

For local installs of IIS, there really isn’t a short answer, so…

Long Answer for locally-hosted or other IIS

There are two solutions from Microsoft, both of which are not quick or simple: use URLRewrite or use URLScan. These solutions are described in Microsoft’s technical blog at remove-unwanted-http-response-headers in the first section.

A third solution is to use the IIS Strip Headers module found at dionach.com. This is a native-code plug-in for IIS that can remove the headers from IIS 7.0 until 8.5. It also has the ability to remove some of the other headers mentioned in this document.

However, as with the minimalistic Apache header, sometimes the complete solution is not worth the extend effort since a very determined attacker will be able to figure out the version of IIS using specialized software fingerprinting.

Microsoft-HTTPAPI/2.0

Short Answer

Add this to the registry:

Long Answer

If the system is running self-hosted WCF, then using the tricks for IIS will not remove this header. Thus, edit the registry key HKLM\SYSTEM\CurrentControlSet\Services\HTTP\Parameters and add/edit DisableServerHeader to be a DWORD with value of 1. Or, simply run this registry file:

However, if registry editing is not allowed, then try something like:

X-Powered-By: ASP.NET

Short Answer

Add this to your web.config:

Long Answer

With the presence of WebResouce.asdx and *.aspx file on a website, the use of .Net is fairly obvious. However, the fairly long string of 22 known characters may aid attacks against a TLS connection. Thus, it is probably best to remove the header.

There could be cases where the above does not work. In those situations:

  1. Open the IIS console.
  2. Choose the web site.
  3. In the IIS section, click on HTTP Response Headers.
  4. In the Actions Pane, choose “X-Powered-By” and delete it.

X-AspNet-Version: 4.0.detailed.version

Short Answer

Put this in web.config:

Long Answer

The X-AspNet-Version header gives the patch-level of .Net installed and makes it much easier for an attacker to determine vulnerabilities in libraries on the server. To remove, add this to web.config:

X-AspNetMvc-Version: 3.x

Short Answer

In Global.asax.cs, this to Application_Start() :

Long Answer

In the application’s Global.asax.cs file, add this to the Application_Start() function to disable the header:

See the reference URL below for more a thorough description of this code.

Overall IIS or ASP.NET web.config suggestions

Other Resources and Credits and references

Most of the knowledge in this page has been collected from old reports and generally known concepts over many years. However, some items were researched again and particularly well written documentation needs to be given credit. Thus, I thank those authors:

This blog post has been mirrored at the Aspect Security blog.