Come impedire a qualcuno di indovinare il token in un link di reimpostazione della password

1

Attualmente ho il seguente set-up per la gestione degli utenti che hanno dimenticato la loro password.

  1. Un utente digita il suo indirizzo e-mail e preme il pulsante della password dimenticata.
  2. Ricerco l'utente che appartiene a quell'indirizzo e-mail e memorizzo una nuova "richiesta di password dimenticata" nel database. L'elemento di richiesta della password dimenticata ha il seguente aspetto:

    Guid ForgotPasswordRequestId;
    Guid UserId;
    DateTime ValidUntil;
    
  3. Genero un token per identificare la richiesta di password dimenticata convertendo la guida di ForgotPasswordRequest su una stringa Base64. Il Guid è una guida di versione 4 (casuale, non basata sul tempo o sull'indirizzo MAC). Controlla questo link MSDN per le note sull'implementazione.

  4. Creo un link come www.example.com/account/ForgotPassword?token=TOKEN che viene inviato all'utente in una e-mail.

  5. Ogni volta che qualcuno visita quel link entro 24 ore, può impostare una nuova password per quell'account.

Penso che le probabilità che qualcuno indovini il token è piccola poiché Guid è un numero di 122 bit (128 bit, meno 6 bit per le informazioni sulla versione). Quindi un hacker avrebbe bisogno di provare, in media, token (2^122 / 2) entro 24 ore prima di riuscire. Se la mia matematica è corretta, questo è 3 * 10^31 token al secondo, che sono sicuro che il mio server non può gestire;). Anche il token che devono indovinare non è in alcun modo correlato all'utente per il quale desidera reimpostare la password.

Tuttavia, è corretto generare il token direttamente da un Guid generato? Esiste comunque un modo per utilizzare un Guid e non un generatore di numeri casuali sicuro per rendere un attacco fattibile? C'è qualche altro problema in questo schema che lo rende non sicuro?

Ho visto questa domanda, sebbene il suo relativo non spiega le migliori pratiche per generare il token.

    
posta Roy T. 10.09.2015 - 09:51
fonte

3 risposte

5

Dovresti creare un token crittografico casuale per questo. Il tuo non è sicuramente abbastanza casuale, e potrebbe essere indovinato molto più veloce del (2 ^ 122/2) che menzioni. L'importanza della casualità crittografica è stata discussa molte volte già in questo forum, ad esempio qui .

Come dici che stai usando .net, dai un'occhiata a ASP.Identity che può generare token per te, usando DataProtectorTokenProvider . Se non si utilizza ASP.Identity (o Owin per quella materia), è possibile anche utilizzare RNGCryptoServiceProvider per generare token casuali sicuri. Non sto dicendo che non potresti farlo da solo, ma è difficile .

Modifica: se stai parlando di un GUID (come fai riferimento ad esso), puoi leggere questa risposta :

To identify a user of an online banking application on the other hand, (or really probably even a password reset function of a site where identity is valuable) GUIDs are definitely inadequate.

    
risposta data 10.09.2015 - 10:49
fonte
2

Potresti includere non solo il codice, ma anche l'identificativo utente nel link per la reimpostazione della password. Ad esempio:

www.example.com/account/forgot-password?user-id=a45sdf48kf345&token=TOKEN

Ogni volta che qualcuno ha visitato il link Forgot Password , è necessario convalidare non solo il token e la relativa data di scadenza ma anche l'id utente prima di reimpostare la password.

In questo schema, l'utente malintenzionato dovrebbe non solo indovinare il token ma anche l'utente per il quale è stato generato.

    
risposta data 26.02.2016 - 23:28
fonte
0

Per migliorare il tuo approccio puoi

  • Utilizza un strong rumore pseudo casuale al posto di GUID
  • Limita il numero di volte in cui qualcuno tenta di accedere a un link di ripristino per un determinato utente, ad es. a 5. È necessario aggiungere userId alla richiesta che si invia e una colonna di conteggio nel database
  • applica il ritardo prima del prossimo tentativo, ad es. 1 sec, 5 sec, 60 sec
  • Blocca l'indirizzo IP per un po 'di tempo se il numero di tentativi ha raggiunto il conteggio massimo. Questo può essere d'aiuto con l'attacco DOS su piccola scala.
  • usa SSL per le tue richieste, in modo che gli utenti non inviino nuove password in chiaro
risposta data 10.09.2015 - 15:37
fonte

Leggi altre domande sui tag