Verifica del parametro "return" nella pagina di accesso

5

La mia pagina di login accetta il parametro "return", che dovrebbe contenere URI per reindirizzare l'utente se non era loggato e ha provato ad accedere alla pagina che non è accessibile da utenti non autenticati. Potrebbe essere qualsiasi cosa dal mio sito.

Come faccio a controllare correttamente quel parametro nel mio codice server, prima di restituire lo stato HTTP 302 con quell'URI all'utente dopo che si è autenticato correttamente nella pagina di accesso?

È sufficiente controllare che uri[0] == '/' && uri[1] != '/' (quindi l'utente malintenzionato non invierà una richiesta come /login?return=http://google.com )?

Può un utente malintenzionato costruire un uri complicato che invierà l'utente vittima a problemi? Naturalmente presumo che le altre pagine non contengano vulnerabilità XSS, la richiesta GET non modifica nulla nel database, ecc.

Se un utente malintenzionato può ingannare la vittima per fare clic sul suo collegamento e l'utente vittima è già connesso, le cose accadranno comunque e non posso fare nulla per impedirlo, tranne implementare misure di sicurezza conosciute come la protezione CSRF, ecc. .

    
posta vbezhenar 06.01.2015 - 13:38
fonte

8 risposte

3

La vulnerabilità di non controllare un parametro a cui viene reindirizzato è chiamato Apri reindirizzamento . Si tratta principalmente di un rischio di phishing, in quanto un utente può fare clic su un collegamento che va a www.google.com (ad esempio per questo argomento si sta eseguendo Google) mentre hanno verificato l'URL prima di fare clic. Tuttavia, vengono reindirizzati dal reindirizzamento aperto a www.evil.com dove non si nota che l'URL è cambiato perché la pagina ha lo stesso aspetto di Google e quindi inseriscono il nome utente e la password di Google nel modulo, inviando le loro credenziali a% % co_de.

Convalida semplicemente www.evil.com per assicurarti che sia solo un percorso relativo.

Ad esempio, in .NET puoi chiamare return con Uri.IsWellFormedUriString impostato su UriKind .

Per altre lingue, potrebbero essere disponibili metodi simili.

Se hai bisogno di scrivere da solo il controllo che hai dichiarato dovrebbe andare bene:

uri[0] == '/' && uri[1] != '/'

vale a dire. il primo carattere è Relative e il secondo non è / .

RFC 3986 specifica il formato di un URL relativo:

 relative-ref  = relative-part [ "?" query ] [ "#" fragment ]

      relative-part = "//" authority path-abempty
                    / path-absolute
                    / path-noscheme
                    / path-empty

Quindi finché controlli il primo carattere è / ed escludi il riferimento al percorso di rete:

A relative reference that begins with two slash characters is termed a network-path reference

che è ora utilizzato dai browser moderni come URL relativo al protocollo , ti stai assicurando che l'URL sia relativo e sicuro contro le vulnerabilità di reindirizzamento aperto.

    
risposta data 07.01.2015 - 12:14
fonte
5

Il modo migliore è creare una whitelist di possibili URL, se il reindirizzamento non fa parte della lista bianca è possibile reindirizzare a una home page predefinita. Tuttavia questo non è troppo flessibile.

Puoi anche regexare l'intera faccenda in modo che assicuri che l'inizio dell'URI sia il tuo sito web, ad es. link e ciò che viene dopo l'ultimo / contiene solo numeri, lettere e amp; o ? e non consentire altri caratteri (si potrebbe anche lavorare con percorsi relativi).

    
risposta data 06.01.2015 - 14:42
fonte
4

Dipende dalla tua fantasia da ottenere. Immagino che questa logica risponda al conto:

// Is this a full URL string?
if(is_valid_url(trim($uri)))
{
    // Redirect user to the default landing page
    redirect(default_url_within_site);
}
else
{
    // It is probably an actual URI string so just append it to your site name
    redirect('www.yoursite.com/'.$uri);
}
    
risposta data 06.01.2015 - 19:55
fonte
1

considera TUTTO l'input dell'utente come EVIL, che significa. dopo aver disinfettato il tuo input, ricostruisci l'url di reindirizzamento per puntare sempre al tuo sito (dominio) e spoglia tutti gli argomenti non in uso per il tuo sistema o che sono 'speciali' in html (quindi url strip codificati). O meglio ancora, lavora solo con la parte "bianca elencata" del tuo sito per tornare, e altri modi per tornare al "fronte". in questo modo puoi accedere solo a un numero limitato di pagine di destinazione che sono più facili da disinfettare.

    
risposta data 06.01.2015 - 14:41
fonte
1

Dovresti controllare l'intero parametro, non solo i primi due caratteri.

Anche se un reindirizzamento (supponendo che tu usi solo quel parametro nell'intestazione Location ) non sia sfruttabile come qualsiasi altra pagina in XSS, ci sono state vulnerabilità note in diversi browser che potrebbero portare a un reindirizzamento XSS attraverso 30x di successo sia in Opera che in Firefox.

Suggerirei di usare espressioni regolari per consentire solo determinati caratteri "sicuri" su quel parametro, come lettere maiuscole, minuscole, numeri, punti e forse barra.

    
risposta data 06.01.2015 - 14:41
fonte
1

Idea difficile prendere tutti i risultati come buoni ma prima di reindirizzare con curl inviare una richiesta con l'opzione seguente abilita e verificare se il risultato Host è il tuo host

    
risposta data 07.01.2015 - 02:07
fonte
1

Per quanto ne so, si tratta di una vulnerabilità di reindirizzamento aperto:

link

Può essere facilmente evitato crittografando il parametro di reindirizzamento con qualcosa come AES, quindi url / base 64 lo codifica.

    
risposta data 07.01.2015 - 02:13
fonte
0

Il rischio non è elevato. L'avversario deve essere in grado di inviare l'utente a un URL con un parametro di ritorno a sua scelta. Se l'avversario era in grado di farlo, molto probabilmente avrebbe inviato l'utente al proprio dominio in primo luogo invece della tua pagina di accesso.

Potrebbe essere possibile utilizzarlo in determinati attacchi di phishing. Ma la maggior parte degli attacchi di phishing copia semplicemente il design della tua pagina di accesso su un URL nel proprio dominio.

Detto questo, la difesa in profondità è solitamente una buona idea. Quindi vale ancora la pena considerare come il parametro di ritorno può essere validato.

Altri hanno sottolineato che è possibile creare una whitelist di URL consentiti. Un approccio diverso sarebbe quello di applicare un codice di autenticazione della firma o del messaggio all'URL.

Se http://example.com/private richiede l'autenticazione, potrebbe reindirizzare a http://example.com/login?return=http://example.com/private&mac=Tej3M9aawsaCihGGXBGABPyyYsQQPX1o3PQeGg . La pagina di accesso può verificare che il MAC sia valido per l'URL di ritorno specificato e non reindirizzare all'URL di ritorno se non dispone di un MAC valido. Può essere una buona idea far dipendere il MAC non solo dall'URL di ritorno ma anche da un cookie.

    
risposta data 07.01.2015 - 01:58
fonte

Leggi altre domande sui tag