Limitazione del parametro di reindirizzamento a un dominio specifico

2

L'utilizzo di PHP per impostare un'intestazione di posizione per il reindirizzamento (ad es. al momento del login dopo essere stato disconnesso) può essere insicuro se il reindirizzamento non specifica un dominio. Ecco un esempio:

header('Location: ' . $_GET['redirect']);

Esiste un modo semplice (non una whitelist) per garantire che il reindirizzamento non lasci il dominio. Forse qualcosa del tipo:

header('Location: /' . $_GET['redirect']); //start forward slash guarantees domain cant change?
    
posta tau 25.01.2018 - 00:17
fonte

2 risposte

1

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 .

    
risposta data 25.01.2018 - 00:58
fonte
2

Il tuo esempio è banalmente ignorabile:

http://yoursite.com/page.php?redirect=/www.google.com

restituisce un reindirizzamento di:

//www.google.com

Che è un URL valido.

Dovresti analizzare l'URL utilizzando una funzione come parse_url , quindi ricostruire un URL igienizzato con i componenti del percorso che desideri. Ad esempio, puoi utilizzare solo path e query frammenti per creare un URL che reindirizza solo all'interno del protocollo, della porta e dell'host correnti.

    
risposta data 25.01.2018 - 00:45
fonte

Leggi altre domande sui tag