Home HTTP HOST Header Injection
Post
Cancel

HTTP HOST Header Injection

Host Header

The HTTP Host header is a request header that specifies the hostname and port number of the server that the client is requesting a resource from. The hostname is the domain name of the server, such as www.example.com. The port number is the number of the port on the server that the resource is hosted on.

The Host header is important because it allows the server to distinguish between different requests for the same resource, even if they come from different clients. For example, if two clients request the URL https://www.example.com/index.html, the server will need to know which client is requesting the resource from www.example.com and which client is requesting the resource from a different website that happens to have the same URL.

In simple words, the Host header is like a name tag for a server. It tells the server which website or application a request is coming from. This is important for servers that host multiple websites or applications, and it is also important for caching systems.

Here is an example of a Host header:

1
Host: www.example.com:80

This header tells the server that the client is requesting the resource from the website www.example.com, which is hosted on port 80.

HTTP Host Injection

When the host header in an HTTP request is flawed or manipulated, it can lead to a serious security vulnerability known as HTTP Host Header Injection. Many web servers are configured to serve a default website, also called the first virtual host, when they receive requests without a recognizable or valid host header.

The problem arises because the host header is controlled by the user, meaning anyone can send requests with arbitrary host headers to the server. There is no built-in mechanism to verify whether the domain specified in the host header actually matches the IP address that initiated the initial TCP handshake.

As a result, attackers can exploit this weakness by tampering with the host header and injecting malicious content. Since the server relies on the host header to determine which website to serve, the injected host header can manipulate the server-side behavior, leading to potentially harmful consequences.

For instance, an attacker could redirect users to a malicious website that closely resembles a legitimate one, tricking them into providing sensitive information. Alternatively, they might use the vulnerability to perform Server-Side Request Forgery (SSRF) attacks, accessing internal systems or resources that should not be exposed to the internet.

Password Reset Poisoning

HTTP Host Injection in password reset poisoning is a specific type of attack that exploits the vulnerability of web applications in handling password reset functionality. It occurs when an attacker manipulates the HTTP Host header during the password reset process to trick the application into sending the reset link or token to a domain controlled by the attacker instead of the legitimate user’s email address. This allows the attacker to intercept the reset link or token, take control of the user’s account, or gain unauthorized access to sensitive information.

Let’s walk through an example to illustrate how HTTP Host Injection can be used in password reset poisoning:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from flask import Flask, request, redirect, 	url_for
import random
import string

app = Flask(__name__)

def generate_reset_token():
    return ''.join(random.choices(string.ascii_letters + string.digits, k=100))


@app.route('/reset_password')
def reset_password():
    token = generate_reset_token()
    reset_link = url_for('reset_password',token=token, _external=True)
    return redirect(reset_link, code=302)

if __name__ == '__main__':
    app.run()

In this code, we have a Flask web application with a single endpoint /reset_password. The reset_password() function generates a random reset token using the generate_reset_token() function. It then uses url_for() to construct a URL for the same reset_password() endpoint but with the generated token as a query parameter. Finally, the function redirects the user to the constructed reset link.

host-1

Now, let’s understand why this code is vulnerable to host header injection:

The vulnerability lies in the url_for() function. The url_for() function is used to generate URLs for specified endpoints in the Flask application. However, in this specific case, the endpoint used is ‘reset_password’, which corresponds to the current function itself.

An attacker can exploit this by sending a malicious HTTP request with a manipulated Host header. Since url_for() uses the current request’s Host header to construct the URL, the attacker can control the domain part of the generated reset link. As a result, the reset link will point to a domain specified by the attacker, rather than the legitimate domain of the application.

For example, if an attacker sends a request with the Host header set to “evil.com”, the generated reset link will be http://evil.com/reset_password?token=[generated_token]. This link provides the attacker with a token, which can then be used to initiate the password reset process, potentially granting unauthorized access to the user’s account.

host-2

Duplicate Host headers

When an attacker injects a duplicate Host header, the server might interpret the request differently. Depending on how the server processes multiple headers, it may end up using the injected Host header instead of the original one.

For example, consider the following request:

1
2
3
GET /example HTTP/1.1
Host: vulnerable-website.com
Host: bad-stuff-here

In this case, the web application might exhibit varied behavior. Some systems will give precedence to the first instance of the Host header, while others may favor the last instance.

Host Override Headers

The X-Forwarded-Host header is an HTTP header that is often used in proxy configurations. It provides information about the original host requested by the client before it went through any proxy servers. This header is useful for servers to determine the original domain requested when the request is passed through a chain of proxy servers.

In some server setups, the X-Forwarded-Host header can be used to rewrite the value of the Host header. When a request with both Host and X-Forwarded-Host headers is received, some web servers may choose to prioritize the value in the X-Forwarded-Host header, effectively overwriting the original Host header value.

To exploit this behavior, attackers can craft a malicious request like the following:

1
2
3
GET / HTTP/1.1
Host: www.example.com
X-Forwarded-Host: www.attacker.com

In this example, the attacker sets Host to a legitimate domain (www.example.com), which is the target domain they want to attack. They then use X-Forwarded-Host to specify their own malicious domain (www.attacker.com).

Besides the widely used X-Forwarded-Host header, several other headers serve a similar purpose and may lead to similar security risks.

1
2
3
4
X-Host
X-Forwarded-Server
X-HTTP-Host-Override
Forwarded

Remediation

To enhance security and mitigate potential vulnerabilities related to Host header manipulation, web applications can implement better practices by using the SERVER_NAME variable and creating a dummy vhost for handling unrecognized Host headers.

This post is licensed under CC BY 4.0 by the author.