Logica di autenticazione del modulo di accesso

3

Sto costruendo il mio modulo di login e voglio assicurarmi che la mia logica sia solida e il più sicura possibile.

1.) Per prima cosa controllo se l'indirizzo e-mail fornito esiste nel database, in caso contrario, mostro un messaggio di errore generico Invalid e-mail address or password. ed esci. Si noti che il messaggio di errore non specifica che l'e-mail non esiste.

2.) Quindi controllo se failed_logins che è memorizzato nel database è maggiore di 5. Se lo è, mostro un messaggio di errore User has been locked out due to excessive invalid logins. e esci. Si noti che questo messaggio viene visualizzato se un account utente è bloccato, ma è stata fornita la password errata. L'ho fatto perché se un account è bloccato, non voglio che un potenziale hacker sia in grado di determinare se ha fornito la password corretta.

3.) Controllare la password confrontando l'hash bcrypt nel database con la password fornita. Se non è corretto, mostra Invalid e-mail address or password. increment failed_logins nel database ed esci.

4.) Controlla il flag activated nel database. Se attivato è impostato su 0, quindi mostra un messaggio di errore User is not activated. Avviso, devono fornire la password corretta per visualizzare questo messaggio di errore.

5.) Valido, imposta failed_logins su 0 nel database e imposta le sessioni.

C'è qualcosa in questa logica che è imperfetto o insicuro? Grazie mille.

    
posta Justin 08.11.2012 - 03:21
fonte

4 risposte

1

Alcuni attacchi a cui pensare:

Trucca il failed_logins cancellando l'ID della sessione. Enumerazione degli account cercando di bloccare gli account esistenti. Esegui gli account amministrativi bloccandoli con tentativi di accesso non riusciti. Enumerazione dei nomi di accesso con la funzione password dimenticata o con registrazione o riferimento ad oggetti diretti non sicuri. Spoofing del tuo indirizzo IP fornendo un elemento di intestazione http x-forwarded-for .

Gestione sessione interrotta: Session Riding (CSRF), Scadenza sessione, Correzione sessione, Problemi con dominio cookie / ambito cartella, memorizzazione ID sessione in testo normale nel database, entropia insufficiente negli ID sessione. Non impostare i flag "sicuro" e "HTTPOnly". Clickjacking. OWASP A9 ...

Mi sono perso qualcosa?

YES

    
risposta data 08.11.2012 - 05:23
fonte
1

Dovresti scambiare i passaggi 1 e 2. È necessario tenere un registro separato dei tentativi di accesso per ogni indirizzo e-mail fornito, a prescindere dal fatto che l'e-mail sia valida o meno. Utilizza le stesse regole di maiuscole e minuscole del tuo database utente per gli indirizzi email.

es.

[email protected], anypassword, = 1 failed_login
[email protected], anypassword, = 2 failed_logins
[email protected], invalidpassword = 1 failed_login
[email protected], invalidpw2 = 2 failed_logins

Potresti reimpostare il numero failed_login per indirizzo email dopo un periodo di tempo casuale (quindi un utente malintenzionato non può dedurre che un indirizzo email non è valido man mano che il messaggio bloccato persiste - questo "simula" un accesso valido per quell'indirizzo email in gli occhi dell'attaccante).

Inoltre, assicurati che il codice per generare l'intera presentazione del messaggio di errore sia impostato nello stesso pezzo di codice. Se viene visualizzato Invalid e-mail address or password , ma viene generato in diverse parti del codice, potrebbero esserci sottili differenze nell'HTML che l'utente malintenzionato potrebbe rilevare e utilizzare a proprio vantaggio. per esempio. se fallisce al punto 1 potrebbe essere generato come <span>Invalid e-mail address or password</span> o se fallisce al punto 3 potrebbe essere <span id="message">Invalid e-mail address or password </span> - non vuoi che queste differenze rilevabili come l'attaccante possa quindi dedurre quale fase il loro tentativo di accesso ha ottenuto, quindi è meglio usare lo stesso codice.

Inoltre, è possibile introdurre un timing in modo che la risposta di login richieda sempre lo stesso tempo per tornare all'utente. È possibile impostare un timer all'inizio del processo e controllare il timer alla fine (a seconda del livello che si ottiene). Quindi se l'intero processo è inferiore a un tempo impostato (ad esempio 1,5 s), il thread viene ritardato fino a quando non è trascorso il tempo totale. Questo interromperà il rilevamento "cieco" di quale passo di accesso è stato raggiunto a causa del tempo di risposta del server.

    
risposta data 08.11.2012 - 13:05
fonte
1

Poiché si desidera nascondere se un determinato indirizzo di posta elettronica esiste o meno nel sistema, sarà necessario rendere gli scenari 1 e 3 più simili. @SilverlightFox suggerisce di aggiungere una pausa in modo che il tempo impiegato dal processo di login sia sempre lo stesso - questo è un passo nella direzione giusta, ma non sufficiente. Infatti, quando un thread dorme , non utilizza la CPU, che è libera di svolgere altre attività. Un aggressore industrioso gestirà decine o centinaia di tentativi di accesso in parallelo e farà rallentare il server a passo di lumaca. In queste condizioni (carico molto pesante), qualsiasi tentativo di hashing di una password (con bcrypt) impiegherà molto tempo - cioè un tempo rilevabile .

Pertanto, al fine di nascondere se un dato indirizzo e-mail è o meno un nome di accesso valido, è necessario organizzare per sempre il calcolo di bcrypt. Inoltre, non si desidera fornire le stesse informazioni tramite il messaggio "account bloccato". Le cose dovrebbero andare così:

  1. Registra sempre il numero di tentativi per indirizzo e-mail, indipendentemente dal fatto che l'indirizzo e-mail esista o meno nel tuo sistema. So che questo è scomodo (in termini di database, avrai bisogno di un'altra tabella aggiuntiva). Se il tentativo di conteggio per un determinato indirizzo email supera 5, si rifiuta l'accesso.

  2. Dai un'occhiata al database, per vedere se l'indirizzo e-mail esiste nel sistema e ottieni il bcrypt salt. Se non lo fa, usi un sale extra fisso. Quindi calcoli incondizionatamente la parte bcrypt. Quindi (e solo allora), se l'output di bcrypt non corrisponde al valore memorizzato, o se è stato usato il sale extra fisso, allora si rifiuta con "Email o password non valida".

  3. Se il tentativo di accesso ha esito positivo, ripristini il "conteggio tentativi" per quell'indirizzo email.

Ora, la tabella aggiuntiva per tenere traccia dei conteggi dei tentativi può essere scomoda in molti modi, perché potrebbe crescere abbastanza velocemente. Potresti fare una variante in cui non hai il tavolo. Invece, può mantenere il conteggio per ciascun utente valido , ma in questo caso è necessario rifiutare i tentativi di accesso con "Email o password non valida" quando il conteggio è 5 uscita abbinata o meno. In altre parole, puoi permetterti di fornire all'utente alcune informazioni sul fatto che il suo account sia bloccato o meno solo se tale informazione viene calcolata indipendentemente dal fatto che l'account esista o meno (tramite la tabella aggiuntiva).

Si può anche dire che bloccare account per un server con accessi remoti è un po 'duro, perché permetterebbe a chiunque di bloccare l'account di qualcuno, per sbaglio o malizia. Il blocco comporta lo sblocco manuale, ad esempio i costi extra di helpdesk. Suggerisco di reimpostare automaticamente tutti i "conteggi dei tentativi" ogni due ore: quindi, il blocco è solo per due ore, il che è sufficiente a scoraggiare gli attacchi di dizionario, rendendo l'intero sistema più robusto ai dinieghi di servizio.

    
risposta data 13.11.2012 - 13:43
fonte
1

Riservatezza. Sembra che tu stia cercando di impedire a un utente malintenzionato di provare un particolare indirizzo email per vedere se esiste nel tuo database. Tuttavia, il tuo schema ha un buco: in realtà non lo raggiunge.

Dato un indirizzo, ad esempio [email protected] , l'utente malintenzionato può provare ad accedere con quell'indirizzo e-mail 6 volte (usando una password improbabile). Quindi, l'utente malintenzionato può provare ad accedere nuovamente.

  • Se l'autore dell'attacco riceve una risposta Invalid e-mail address or password. , l'utente malintenzionato può dedurre che questa email non esiste nel tuo database.

  • Se l'autore dell'attacco riceve un User has been locked out due to excessive invalid logins. , l'utente malintenzionato può dedurre che questa email esiste nel tuo database.

Integrità. Il tuo metodo di convalida delle password sembra soddisfacente e dovrebbe impedire a un utente malintenzionato di effettuare una ricerca nel dizionario sulla password di un particolare utente.

Non impedirà a un utente malintenzionato di eseguire un numero limitato di tentativi su un numero elevato di password degli utenti. Supponiamo che un utente malintenzionato possa in qualche modo elencare un insieme di indirizzi e-mail che hanno un accesso con il tuo servizio (magari con una ricerca Web intelligente o sfruttando la violazione di riservatezza sopra o qualcosa del genere; non so se questo sia effettivamente possibile nel tuo caso ma esploriamo le conseguenze se lo è). Quindi un utente malintenzionato può eseguire iterazioni su tutti questi account e fare 5 ipotesi sulla password per ciascun account.

Ricerca recente ha rilevato che un utente malintenzionato può effettuare 10 tentativi per ciascun account sarà in grado di compromettere circa l'1% degli account. Estrapolando, possiamo aspettarci che nella tua situazione, un utente malintenzionato sia in grado di compromettere circa lo 0,5% degli account, effettuando 5 tentativi sulla password per ciascun account di cui è a conoscenza l'autore dell'attacco.

È possibile rendere più difficile questo tipo di attacco induttivo tenendo traccia del numero di tentativi di accesso non riusciti per ogni indirizzo IP e bloccando temporaneamente gli accessi dagli indirizzi IP che hanno un numero elevato di tentativi di accesso non riusciti. Tuttavia, questa non è una difesa perfetta (un attaccante con una botnet può facilmente aggirare questo).

Disponibilità. Sarebbe facile per un utente malintenzionato bloccare un utente mirato: tutto ciò che l'utente malintenzionato deve fare è provare ad accedere 6 volte con una password improbabile, e ora quell'utente non essere in grado di accedere senza contattare il team di supporto. Questo potrebbe essere un rischio accettabile. La buona notizia è che se ciò accade frequentemente, lo saprai e in quel momento puoi mettere in atto delle difese.

Soluzioni standard. Hai chiesto se ci sono soluzioni standard. Per quanto ne so, non ci sono soluzioni standard. Tuttavia, in un filone correlato, potreste essere interessati a questo documento accademico, che cerca di evitare l'uso di utenti popolari: se troppi altri utenti hanno scelto la stessa password, i nuovi utenti non sono autorizzati a utilizzarlo. Il documento ha alcune strutture dati intelligenti per assicurarsi che questo non crei nuovi problemi di sicurezza.

risposta data 12.11.2012 - 03:58
fonte

Leggi altre domande sui tag