HTTP Host header attacks are any attacks performed by manipulating the value of the Host header in an HTTP request. The attacker sends HTTP requests to a web application or web API and forges the value of the Host header or adds other headers that take precedence over the value of the Host header. This is also often called a Host header injection attack (the name used by OWASP).
Web servers usually host several websites or web applications that have different domain names but are accessed via the same IP address. The use of such virtual hosts is what makes the Host request header necessary – the web server uses its value to direct the request to the correct website or web application.
The Host header is a simple text field containing a hostname such as example.com, www.example.com, subdomain.example.com, etc. Here is an example of a legitimate request with a Host header:
GET /samples/snippet.html HTTP/1.1
Host: www.example.com
This request tells the web server to supply the /samples/snippet.html resource located on the www.example.com host, in effect requesting www.example.com/samples/snippet.html.
Setting the Host header to an arbitrary value when sending an HTTP request is trivial – all the attacker needs to do is send the request manually using a free tool like telnet or cURL. The attacker’s challenge lies in delivering that request to the intended web application.
If the sender specifies a Host header that is incorrectly formed or not known to the web server, most web servers will pass the request to the first virtual host on the list. In such cases, it’s possible to send requests with arbitrary Host headers to the first virtual host but not to other virtual hosts on the same server. However, some servers may reject all requests with incorrect or unknown Host values, eliminating this avenue of manipulation.
You can also manipulate Host headers by using host override headers. The web server might be configured to accept the X-Forwarded-Host header and use its value to rewrite the original Host header value before processing. To take advantage of this, you could send requests similar to the following, where www.example.com is the legitimate host you want to replace with the malicious www.vulnweb.com:
GET /index.php HTTP/1.1
Host: www.example.com
X-Forwarded-Host: www.vulnweb.com
Yet another option for an attacker is to supply duplicate Host headers. If systems differ in how they interpret multiple Host headers in one request, a Host header injection vulnerability may result. For the following request, this could happen if the web server directs the request to the site specified in the first Host header it encounters, while the web application assumes that the host is defined by the last Host header:
GET /index.php HTTP/1.1
Host: www.example.com
Host: www.vulnweb.com
Most web applications are designed to be deployed on any host and any domain, but sometimes they may need to know what host/domain they are deployed on. This is often required when the application needs to build an absolute URL, for example, for email functionality.
Major web applications such as CMS systems usually ask you for the hostname during initial setup and store that value in safe configuration files. However, it is also common for application developers to assume they can simply take the hostname from the Host header of HTTP requests. This violates a fundamental law of application security: never blindly trust user input or any other user-controllable data.
If your application uses the hostname from the Host header without sanitizing it, an attacker may use this to supply malicious content from a host they control. The consequences depend on how your vulnerable website uses the Host header value.
The following are some of the most common attacks performed using the Host header. Note that the impact of the attack depends on how the web application uses the Host header value.
The best way to detect vulnerabilities that make Host header attacks possible depends on whether they are already known or unknown.
The best way to prevent all Host header attacks is to never use Host header values anywhere in your web applications. While it is common to use the Host header to identify the application host automatically, it is more secure to specify the hostname manually.
When using a web application framework, you can use the hostname value stored by the framework. Frameworks ask you for the hostname during setup and then store that value securely in a configuration file (e.g. Joomla, Drupal), database (WordPress), environment variable (Laravel), or service registry (Kubernetes DNS).
If your application needs the value of the Host header to work properly and there is no workaround, build a whitelist of accepted host names. For example, if your web server serves 10 hosts, you should only accept these 10 hostnames as Host header values.
A Host header attack, also known as Host header injection, happens when the attacker provides a manipulated Host header to the web application. The consequences of such attacks vary depending on how a web app processes the Host header content.
Read about password reset poisoning, which is the most common use of Host header attacks.
Host header attacks may be used to perform attacks such as web cache poisoning and password reset poisoning. Web cache poisoning lets an attacker serve malicious content to anyone who requests a cached web page. Using password reset poisoning, the attacker can obtain a password reset token and reset another user’s password.
To avoid Host header attacks, follow a fundamental rule of cybersecurity: never trust any input that can be manipulated by the user. In this case, this means never using Host header values without validation. If you absolutely must use the Host header to identify the web server host, use a whitelist of allowed host names.
Read more about secure coding practices for web applications.