La mia applicazione web mi consente di inviare il modulo di login per reindirizzare a una determinata pagina del sito Web dopo aver effettuato l'accesso. Ad esempio, se l'utente passa all'url http://localhost/login.php?returnto=%2FconfirmEmail.php
, dopo aver completato la procedura di accesso, automaticamente reindirizzato a http://localhost/confirmEmail.php
.
Dopo aver completato la procedura di accesso, ho usato il seguente codice per convalidare l'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"] ) );
}
Mi piacerebbe sapere se questo codice è sicuro o sarà ancora possibile per un utente malintenzionato causare il reindirizzamento della pagina a un sito Web esterno (o ad altre posizioni dannose)?
Aggiornamento: in precedenza, il mio codice per garantire che i collegamenti fossero locali era il seguente:
...
if ( $cleanString[0] !== '/' ) { //All local urls should start with '/'
return FALSE;
}
...
Come indicato da vari commenti , questo considererà validi gli URL relativi al protocollo (ad esempio //google.com). Ho quindi aggiornato il codice sopra riportato per tenerlo in considerazione.