La risposta breve
No. Questo non è sicuro e non dovrebbe essere fatto. In realtà, questo è l'ultimo di OWASP Top 10 :
A10. Unvalidated Redirects and Forwards
Web applications frequently redirect and forward users to other pages and websites, and use untrusted data to determine the destination pages. Without proper validation, attackers can redirect victims to phishing or malware sites, or use forwards to access unauthorized pages.
Phishing e diffusione di malware
Un utente malintenzionato può creare un URL per reindirizzare a qualsiasi pagina desiderata e quindi diffonderlo ovunque:
http://trusted.com/index.php?redirect=http%3A%2F%2Fmalicious.com
L'URL dannoso potrebbe essere offuscato per evitare il rilevamento da parte dell'utente tramite la codifica URL di tutti i caratteri in modo da ottenere una stringa come %68%74%74%70%3A%2F%2F%6D%61%6C%69%63%69%6F%75%73%2E%63%6F%6D
.
Ora un utente che fa clic su quello che sembra un normale collegamento sicuro al tuo sito può finire ovunque:
- Su un sito che sembra esattamente come il tuo, chiedendo nome utente e password. Boom, account rubati.
- Un sito che diffonde malware in base al download. Potresti provare a sostenere che questo non è un tuo problema, dal momento che tecnicamente non è il tuo sito che lo diffonde. Non sono sicuro che la vittima sarebbe d'accordo.
- Qualsiasi cosa. Vuoi che gli utenti facciano clic sui link al tuo sito e finiscano con contenuti illegali o NSFW o NSFL?
Se questo viene fatto dopo che l'utente ha effettuato l'accesso, come suggerito nella domanda, è ancora più pericoloso dal momento che in realtà nella tua pagina l'inserimento delle credenziali rafforza la convinzione degli utenti che è effettivamente sul tuo sito. Sarebbe così semplice pubblicare un tipo di pagina "password errata, riprova" dopo l'accesso.
Iniezione di intestazione
Come già affermato da Steffen Ullrich nella sua risposta a questa domanda ea me in questo risponde a un'altra domanda, su versioni di PHP precedenti alla 5.1.2 che potrebbero essere utilizzate per l'header header.
Che cosa fare invece
Whitelist o convalida
Come spesso accade, la soluzione è fare da whitelist. Ecco un esempio di PHP:
$param = $_GET["redirect"];
$allowed = array(
"index" => "index.php",
"blog" => "blog/index.php",
// ...and so on...
);
$redirect = isset($allowed[$param]) ? $allowed[$param] : "index.php";
header('Location: '.$redirect);
Questo sarà noioso se ci sono molte pagine a cui vuoi essere in grado di reindirizzare. A seconda dell'aspetto dei tuoi URL, puoi convalidare gli URL per il tuo sito. Ad esempio se sono nella forma http://trutsted.com/?pageid=1234
puoi accettare solo il paginato da reindirizzare e verificare che sia effettivamente numerico.
Controllo Referente
Se desideri che i collegamenti di reindirizzamento funzionino dal tuo sito, puoi controllare l'intestazione del referer HTTP della richiesta. Questo potrebbe incorrere in alcuni problemi se pubblichi il tuo sito su HTTP e HTTPS, poiché se si collega da una pagina HTTP a una pagina HTTPS l'intestazione del referente non verrà inviata.
Ecco alcuni esempi di codice:
$headers = apache_request_headers();
$referer = isset($headers['referer']) ? parse_url($headers['referer'], PHP_HOST) : "";
if($referer == "trusted.com") {
//Do the redirect. If you want your code to be safe on old PHP versions,
//you will need to filter out newlines or just URL encode the URL.
}
else {
//Inform the user of the problem or just redirect to your index page.
}
Altre letture
-
OWASP cheat sheet su reindirizzamenti non convalidati. (Uno degli esempi su come non farlo qui è quasi identico a come l'hai fatto nella tua domanda.)
-
Troy Hunt ha un grande contributo su questo argomento.