Host header injection is a web application attack where the attacker provides a false Host header to the web application causing it to behave in an unpredicted way. This attack has been used to find vulnerabilities in password reset functionalities for years and shows no sign of going anywhere. The attack is easy to pull off and can be leveraged to achieve account take over(ATO).
Before we start talking about host header injection you need to fully understand what the host header is. The “Host” request header specifies the host and port number of the server to which the request is being sent. As shown below the host header is set to “w3schools.com”:
Remember that the HTTP protocol is at the application layer of the OSI model. When your browser sends an HTTP request to a server it sends it to the server's IP address not the host header. If a server with a single IP has multiple websites on it the Host header is used by the server to route the request to the correct virtual host. In other cases there is a single website is listening on a specific port and the host header isnt used at all when routing traffic to the correct site.
Most developers think that the host header cannot be controlled by users but this is a misconception. In reality users have full control over the host header and it can be set to anything.
As shown in the image above we changed the Host header to “attacker.com”. The next step is to send the request to the target. Since many developers believe the Host header cannot be tampered with, they may use it to form the password reset link used when emailing it to the user. An example of such code can be found below:
As you can see the developer is using the variable “$_SERVER['HTTP_HOST']” to form part of the password reset link. The “$_SERVER['HTTP_HOST']” variable stores the value of the Host header found in the HTTP response. Since this value can be controlled by the attacker we can put it in our malicious domain. When the application goes to form the password reset link it will use the malicious domain and email the link((https://attacker.com/passwordReset?token=HSGSH7^&j)) to the user. When the user clicks the password reset link their token will be sent to the attacker's domain allowing them to reset the targets password and login.
A lot of developers trust the “Host” header and this trust can be leveraged by an attacker. For example if the host header is used to create a password reset link this could be abused by an attacker to steal password reset tokens. The attack is super easy to check for as it only requires changing a single variable. If the attack is successful it could be leveraged to compromise user accounts by stealing their password reset tokens, resetting their password, and logging into their account.