Skip to main content

Uncontrolled external site redirect

Need

Controlled and secure external site redirects

Context

  • Usage of Scala for building scalable and functional applications
  • Usage of play.api.mvc for handling HTTP requests and responses in Play Framework

Description

Non compliant code

import play.api.mvc._

def redirectTo(url: String) = Action {
Redirect(url)
}

In the above code, the "redirectTo" function accepts a URL as a parameter and redirects the user to that URL. This function is vulnerable to uncontrolled external site redirects because it does not validate or sanitize the input URL.

An attacker could manipulate the 'url' parameter to redirect users to a malicious site. This is typically done by tricking users into clicking a link that appears legitimate but is manipulated to include a redirected URL. For example, an attacker could send an email to users with a link that appears to lead to the application but instead leads to the attacker's site.

The vulnerability lies in the lack of control over the 'url' parameter in the 'Redirect' function. Without any checks in place, the application blindly trusts the input and redirects the user to potentially harmful sites. This can lead to phishing attacks, where the attacker tricks the user into revealing sensitive information.

To fix this vulnerability, the application should validate the 'url' parameter to ensure it leads to a trusted site before redirecting. This could be done by maintaining a list of trusted URLs and checking the input against this list. If the URL is not in the list, the application should not perform the redirect.

Steps

  • Validate the redirect URL: Before redirecting, validate the URL to ensure it is a trusted and expected destination.
  • Use a whitelist: Maintain a whitelist of trusted URLs and only allow redirects to URLs in the whitelist.
  • Sanitize user input: If the redirect URL is based on user input, sanitize the input to remove any potentially malicious characters or scripts.
  • Implement a redirect validation mechanism: Add a mechanism to validate the redirect URL, such as checking if it belongs to the same domain or has a specific prefix.
  • Use a secure redirect method: Instead of using a simple redirect, consider using a more secure method like a POST request or a server-side redirect.
  • Implement a redirect confirmation page: Add an intermediate page that confirms the redirect and allows the user to review and approve the destination before proceeding.
  • Implement rate limiting: Limit the number of redirects a user can make within a certain time period to prevent abuse or excessive redirects.
  • Keep the redirect logic up to date: Regularly review and update the redirect logic to ensure it remains secure and effective against new vulnerabilities.

Compliant code

import play.api.mvc._
import java.net.URL

val trustedDomains = List("www.trusteddomain1.com", "www.trusteddomain2.com") // Add your trusted domains here

def redirectTo(url: String) = Action {
try {
val urlObj = new URL(url)
if (trustedDomains.contains(urlObj.getHost)) {
Redirect(url)
} else {
BadRequest("Invalid redirect URL")
}
} catch {
case _: Exception => BadRequest("Invalid URL format")
}
}

The updated code includes a list of trusted domains. When a redirect request is made, the URL is parsed and the host is extracted. If the host is in the list of trusted domains, the redirect is allowed. If not, a "Bad Request" response is returned.

This approach ensures that only trusted URLs are allowed for redirection, preventing attackers from manipulating the redirect to untrusted sites.

The URL parsing is done in a try-catch block to handle any exceptions that might occur if the URL is not in a valid format. If an exception is caught, a "Bad Request" response is returned.

This solution addresses the vulnerability by implementing a whitelist of trusted domains and validating the redirect URL against this list. It also sanitizes user input by validating the URL format and host.

Remember to keep the list of trusted domains up-to-date and review the redirect logic regularly to ensure it remains secure and effective against new vulnerabilities.

References