Unvalidated redirects and forwards are when an application uses untrusted data to redirect a user to a new webpage. This poses a security threat since an attacker can use the application to redirect unsuspecting users to a malicious site in a phishing scam. Unvalidated redirects and forwards are in the OWASP top ten security vulnerabilities.

Unvalidated Redirects and Forwards Examples

In these examples the URL is sent to the backend server from the user. The server processes the requests and then redirects to the URL supplied.

Form Hidden Fields
Front End

<form action="processForm.php" method="POST">

    <input type="text" name="someUserInput">

    <input type="hidden" name="redirect" value="mysite.com/formIsValid.html">

</form>

Back End Processing

// processForm.php

$destination = $_POST['redirect'];
$someInput = $_POST['someUserInput'];

if($someInput == 'a valid value') {
    //redirect
    header('Location: ' . $destination);
}

 

URL Parameters
Front End

<a href="mysite.com/trackredirect.php?destination=partnersite.com">Check out our partner site</a>

Back End Processing

// trackredirect.php

$destination = $_GET['destination'];

// ...track the redirect somehow...

//redirect
header('Location: ' . $destination);

 

Unvalidated Redirects and Forwards Security Risks

In the previous examples an attacker could enter untrusted data in the form or the URL parameters to redirect to a malicious site. Users are inclined to trust the malicious form or link since it originates from a trusted URL. The unsuspecting user is then redirected to an untrusted location. The risk is that your application facilitates phishing scams, and harms users.

In some cases attackers can use the forwarded URL to bypass security checks and gain unauthorized access to the application if the destination URL does not correctly validate the user’s authorization. The risk in this case is authorization bypass in the application that could allow an attacker to manipulate the application in unintended ways.

OWASP has more information on the risks of unvalidated redirects and forwards

 

Preventing Unvalidated Redirects and Forwards

There are several ways to prevent unauthorized redirects and forwards. The first is to not use user supplied input to determine a redirect value. In the previous form example the processForm.php file could determine the correct location to redirect upon success. It could use the form being processed or it could be a dedicated form processing script with only one redirecting location.

// processForm.php

$someInput = $_POST['someUserInput'];

if($someInput == 'a valid value') {
    //redirect
    header('Location: mysite.com/formIsValid.html');
}

Another solution is to use a keyed value that is stored server side. In the second example the trackredirect.php file could use a key to determine the partner to redirect to and store the URL in the server side script. The link could then be mysite.com/trackredirect.php?destination=partnerOne and the trackredirect.php could use that key to determine the correct and safe URL.

// trackredirect.php

$destination = $_GET['destination'];

// ...track the redirect somehow...

//redirect
$urls = array('partnerOne' => 'partnersite.com');
if (isset($urls[$destination])) {
    header('Location: ' . $urls[$destination]);
} else {
    // unsafe
}

Finally, if a url must be sent from the user to the application, then a whitelisting mechanism should be in place to validate a URL as a trusted URL and if the URL is internal to the application, validate that the user is authorized to navigate to the URL. This is the least preferred approach but provides some safety rather than blindly redirecting.

// trackredirect.php

$destination = $_GET['destination'];

// ...track the redirect somehow...

//redirect
$whitelistedUrls = array('partnersite.com', 'anothersite.com');
if (in_array($destination, $whitelistedUrls)) {
    header('Location: ' . $urls[$destination]);
} else {
    // unsafe
}