Mi aplicación web me permite indicar al formulario de inicio de sesión que redirija a una página determinada en el sitio web después de iniciar sesión correctamente. Por ejemplo, si el usuario va a la url http://localhost/login.php?returnto=%2FconfirmEmail.php
, luego de completar el proceso de inicio de sesión, se redirige automáticamente a http://localhost/confirmEmail.php
.
Después de completar el proceso de inicio de sesión, usé el siguiente código para validar la URL:
function isValidReturnURL( $input ) {
if ( !is_string( $input ) ) { //Input is not a string
return FALSE;
}
$cleanString = trim( urldecode( $input ) );
if ( !strlen( $cleanString ) ) { //Input is an empty string
return FALSE;
}
//Edit: I updated the following code (see below)
$urlHost = parse_url( $cleanString, PHP_URL_HOST );
if ( !empty($urlHost) ) { //All local urls will be relative
return FALSE;
}
//End edit
return TRUE;
}
if ( isValidReturnURL( $_GET["returnto"] ) && $continue ) {
header("Location:" . urldecode( $_GET["returnto"] ) );
}
Me gustaría saber si este código es seguro o si un atacante podría hacer que la página se redirija a un sitio web externo (oa otras ubicaciones maliciosas).
Actualización: Anteriormente, mi código para garantizar que los enlaces fueran locales era el siguiente:
...
if ( $cleanString[0] !== '/' ) { //All local urls should start with '/'
return FALSE;
}
...
Como se indica en varios comments , esto considerará que las URLS relativas al protocolo (por ejemplo, //google.com) son válidas. Por lo tanto, actualicé el código anterior para tenerlo en cuenta.