Maybe something like:
header('Location: /' . $_GET['redirect']); //start forward slash guarantees domain cant change?
No, una barra in avanti principale non ti protegge da reindirizzamenti aperti .
Un utente malintenzionato potrebbe eseguire una query sullo script come ...
https://yoursite.example/file.php?redirect=/malicious.example
... risultante in Location: //malicious.example
che viene considerato come un URL relativo al protocollo che il browser interpreterà come reindirizzamento a https://malicious.example
.
Questa notazione funziona anche per gli URL in altri contesti, ad es. Link HTML:
'<a href="//malicious.example">...</a>'.
Is there a simple way (not a whitelist) to ensure that the redirect not leave the domain.
Un approccio semplice e alternativo alla risposta di @ David è il controllo di una barra e di un successivo carattere alfanumerico, o della sequenza iniziale /./
. Entrambi non possono mai portare alla rappresentazione di un URL assoluto.
Nota che nelle vecchie versioni di PHP dovevi anche disinfettare un valore di intestazione fornito dall'utente per i ritorni a capo / riga, altrimenti potreste abilitare gli attacchi di header header.
Dal tuo commento di follow-up:
what if it started with a protocol and hostname? eg, header('Location: https://domain.com' . $_GET['redirect'])
is there a way around that?
Questo è sicuro solo se si impone che il primo carattere fornito dall'utente sia una barra. Altrimenti, un attacco semplice sarebbe .malicious.example
, reindirizzando al sottodominio controllato dagli attacker https://domain.com.malicious.example
. In alternativa, anche @malicious.example
funziona, dal momento che trasforma domain.com
nel nome utente per l'autenticazione con il dominio malicious.example
.