Prevention of uncontrolled external site redirects through proper validation and sanitization of the Host header
import play.api.mvc._
object Application extends Controller {
def redirect = Action { request =>
val host = request.headers.get("Host").getOrElse("default.com")
val destination = "http://" + host
Redirect(destination)
}
}
The above code is an example of a Scala backend application that uses the Play framework. The vulnerability lies in the
redirect
function, which takes a request and redirects the client to the URL specified by the "Host" header of the request.
The
request.headers.get("Host").getOrElse("default.com")
line of code is where the Host header is read from the incoming HTTP request. If there is no Host header present, it defaults to "default.com".
Then, the
val destination = "http://" + host
line creates a string that represents the destination URL for the redirect. The destination URL is constructed by concatenating "http://" with the value of the Host header.
Finally, the
Redirect(destination)
line sends a redirect response back to the client, which causes the client's browser to make a new request to the destination URL.
The vulnerability here is that the server blindly trusts the Host header from the client and uses it to construct the redirect destination. This is known as a Host Header Injection vulnerability. It allows an attacker to manipulate the Host header and cause the server to redirect the client to an arbitrary URL. This could be used for phishing attacks, where the attacker tricks the client into visiting a malicious website that looks like a legitimate one.
import play.api.mvc._
object Application extends Controller {
val allowedHosts = List("trusted.com", "secure.com") // Add your trusted domains here
def redirect = Action { request =>
val host = request.headers.get("Host").getOrElse("default.com")
if (allowedHosts.contains(host)) {
val destination = "http://" + host
Redirect(destination)
} else {
BadRequest("Invalid host")
}
}
}
The updated code now includes a list of allowed hosts (
allowedHosts
). This list should contain all the trusted domains that your application is allowed to redirect to.
In the
redirect
action, we first retrieve the 'Host' header from the request. If no 'Host' header is found, we default to "default.com".
Next, we check if the retrieved host is in our list of allowed hosts. If it is, we proceed with the redirection as before. If it's not, we return a "Bad Request" response.
This way, we ensure that our application only redirects to trusted domains, effectively mitigating the Host Header Injection vulnerability.
Remember to keep your list of allowed hosts up-to-date and as restrictive as possible to minimize the attack surface.
Also, consider implementing additional security measures such as input sanitization, strict validation, rate limiting, and regular updates to the Play framework and its dependencies.