Link per la reimpostazione della password: valore casuale o messaggio autenticato?

8

Quale è meglio?

  1. Crea un token di reimpostazione password crittografato a prova di manomissione che contiene l'ID utente e la data di scadenza all'interno del token crittografato.

  2. Genera un token casuale e memorizzalo nel database con l'id utente e la data di scadenza. Cerca il token quando l'utente fa clic sul link.

Un vantaggio che posso vedere con # 2 è che si mantiene il controllo su questi token. Se vuoi scadere prima, puoi farlo. Una difficoltà che vedo con # 1 è assicurarsi che i token che invii siano davvero sicuri ea prova di manomissione. Ti affidi completamente a non rovinare la crittografia.

ASP.NET 2.0 ha un metodo integrato per generare token di reimpostazione della password?

    
posta John 22.02.2013 - 23:31
fonte

5 risposte

12

Creare un token casuale che non contenga assolutamente nessuna informazione e collegarlo nel database con un nome utente e un tempo di scadenza è di gran lunga la soluzione migliore.

La crittografia (e l'hashing) viene utilizzata per archiviare e trasferire dati che devono essere assolutamente inviati. Se esiste un modo per fare qualcosa senza dover inviare quei dati, crittografati o meno, che forniscono pari funzionalità e sicurezza, è necessario utilizzare tale metodo. In altre parole, la crittografia dovrebbe essere l'ultima risorsa per proteggere i dati.

    
risposta data 23.02.2013 - 00:28
fonte
4

Questi token sono equivalenti di password e come tali devono soddisfare requisiti simili. Ma di gran lunga il più grande è che non deve essere arbitrariamente indovinato da un avversario. Dovrebbe quindi essere indistinguibile dai dati casuali.

Quando codifichi qualsiasi dato, ovviamente deve essere crittografato. Ora, questo probabilmente implicherà un certo livello di rolling your own, o almeno di mettere insieme i primitivi di crittografia, che probabilmente non farai (Vedi: Non essere un Dave ).

Quindi, ciò significa che la soluzione più semplice e sicura è quella di creare un token molto casuale e memorizzarlo con hash / salted nel database, nonché un id per quel token. Unisciti all'ID e al token e serializzalo su hex o Base32 e invialo all'utente. Quando il token ritorna, usa l'id per afferrare il token / sale dal database e hash il resto del token per vedere se corrisponde.

Devi assicurarti diverse cose aggiuntive sui token poiché saranno nelle e-mail delle persone.

  • Assicurati che abbiano un'entropia sufficientemente alta da resistere alle supposizioni
  • Devono essere abbastanza brevi da codificare in un URL comodamente
  • Devono scadere dopo una finestra di tempo ragionevolmente breve come saranno nelle caselle di posta elettronica della gente
  • Devono essere monouso solo
risposta data 23.02.2013 - 09:35
fonte
2

È possibile codificare il tempo di scadenza in un token e utilizzare un HMAC, ma in genere una reimpostazione della password implica la visita a un URL specifico. Di solito per semplificare le cose per l'utente, uno include il token nell'URL come un campo GET.

Volendo mantenere l'URL relativamente piccolo e composto solo da caratteri stampabili, probabilmente codifichi il timestamp come numero intero e utilizzi impostazioni a larghezza fissa. Questo deve specificare l'utente, la scadenza e il MAC. Lo definirei affidabile, ma non senza una sorta di sforzo di codifica.

Dato che devi comunque colpire un database per le password e non ci vuole alcun pensiero per codificare un valore casuale a larghezza fissa, però, mi piacerebbe andare con quello. A parità di tutti gli altri (e penso che sia piuttosto uguale), facile vincere. Bonus aggiuntivo: minore utilizzo della CPU.

    
risposta data 22.02.2013 - 23:56
fonte
2

È un tema comune. Lo scenario n. 1 è un ottimizzazione dello storage rispetto allo scenario n. 2. In # 2, devi generare e memorizzare un lato del server con valore casuale. Questo ti dà tutto il controllo che desideri, ma richiede una colonna aggiuntiva nel tuo database, o qualcosa del genere. Lo scenario scarica questo requisito di archiviazione lato client. Poiché il client non può essere considerato attendibile, è necessario aggiungere al link un controllo di integrità, ad esempio un MAC ; la crittografia non è necessaria perché non c'è nulla nel link di reset che è necessario mantenere segreta dall'utente (l'utente conosce già il suo nome e quando ha chiesto la reimpostazione della password), ma si desidera impedire a un client malintenzionato di creare un falso ripristina il collegamento, quindi il MAC.

I contenuti del token, nello scenario # 1, devono quindi includere tutti i dati necessari per applicare il criterio di reimpostazione della password, ma hanno scelto di non archiviarli sul server; questo significa il nome utente e una data / ora (tempo in cui è stato avviato il processo di reimpostazione della password o tempo di scadenza). Si potrebbe voler includere un hash della password precedente nell'input al MAC (non necessariamente nel token) se si desidera impedire all'utente di riutilizzare il link di ripristino più volte.

L'elaborazione e la verifica di un MAC non richiede molte risorse, probabilmente un po 'meno che generare un token casuale e archiviarlo in un database (l'accesso al database sarà molto più costoso della crittografia). Tuttavia, è probabile che questo effetto sia comunque trascurabile (i database sono veloci). Uno svantaggio dello scenario n. 1 è che è necessario mantenere una chiave segreta sul server, condivisa tra i front-end (se ne hai diversi), resiliente al riavvio (quindi non una chiave solo nella RAM, a meno che tu non sia pronto a invalidare tutti i link per reimpostare la password quando il server si riavvia), e, ovviamente, al riparo dagli intercettatori.

Il token casuale (scenario # 2) è probabilmente più semplice, oppure, se preferisci, più difficile da sbagliare . Quale è una buona ragione per raccomandarlo.

    
risposta data 23.02.2013 - 00:34
fonte
2

Raccomando questo articolo di Troy Hunt: Tutto quello che hai sempre voluto sapere come creare una funzione di reimpostazione della password sicura

Ecco cosa sta dicendo su come gestire il token di reset:

What we want to do is create a unique token which can be sent in an email as part of the reset URL then matched back to a record on the server alongside the user’s account thus confirming the email account owner is indeed the one attempting to reset the password. For example, the token may be “3ce7854015cd38c862cb9e14a1ae552b” and is stored in a table alongside the ID of the user performing the reset and the time at which the token was generated (more on that in a moment). When the email is sent out, it contains a URL such as “Reset/?id=3ce7854015cd38c862cb9e14a1ae552b” and when the user loads this, the page checks for the existence of the token and consequently confirms the identity of the user and allows the password to be changed.

C'è anche un cheat sheet sul wiki OWASP: Password dimenticata Cheat Sheet ma loro non dire se è meglio o meno memorizzare le informazioni nel database.

    
risposta data 23.02.2013 - 14:24
fonte

Leggi altre domande sui tag