2013-05-23 13 views
5

Ho letto molto qui e in altri luoghi sull'utilizzo di un cookie per l'opzione "ricordami", ma quello che sto cercando è un modo per progettare un cookie per registrare il successo di un'autenticazione a due fattori. Questo è ciò che, ad esempio, Google fa: se il secondo passo riesce (ad esempio, hai inserito il codice che hai ricevuto via SMS), allora imposta un cookie buono per un periodo di tempo (ad esempio, 30 giorni) che significa che il il secondo passo può essere bypassato. Chiamalo "cookie di verifica". La mia comprensione è che se in quel momento si disconnette e poi di nuovo, non farà il secondo passo, ma solo il primo passo. (Ho provato questo e quello sembrava essere il caso.)È necessario il cookie per memorizzare l'autenticazione a due fattori riuscita (accesso non persistente)

La mia domanda è come progettare questo cookie. Un'idea è quella di inserire l'ID utente e un numero casuale a 128 bit nel cookie, e quindi di memorizzare quel numero nel database insieme all'ID utente. Questo è ciò che Charles Miller consiglia (http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/) per i cookie di accesso permanente.

Tuttavia, non è abbastanza buono, penso. Il problema è che, poiché l'utente utilizza un'autorizzazione a due fattori, qualunque sia il cookie utilizzato per registrare che il secondo passaggio ha avuto esito positivo, dovrebbe essere più sicuro di quanto avverrebbe con un'autorizzazione a un fattore.

Quello che voglio evitare è questo: il cracker ha le password hash/salate dal database e in qualche modo ha ottenuto la password. Se lui/lei ha così tanto, presumo che sia disponibile anche il numero casuale a 128 bit presente nel cookie di verifica. (Se il cracker ha ottenuto la password in altro modo e non ha il database, il cookie di verifica è sicuro a meno che non abbia accesso fisico al computer.Sono solo preoccupato per il caso compromesso del database.)

Forse un'idea è di crittografare il numero casuale a 128 bit? (Deve essere bidirezionale, non un hash.) La chiave di crittografia sarebbe accessibile per l'applicazione, forse memorizzata, tuttavia le credenziali del database sono.

Qualcuno ha implementato quello che sto chiamando un cookie di verifica (non un cookie di accesso persistente) e può dirmi (noi) come è stato fatto?


UPDATE: Pensando a questo, che cosa penso sia abbastanza sicuro sarebbe questo: Biscotto si compone di userID e 128 bit di numeri casuali - chiamano R.

database contiene password e R, ogni hash e salato (ad esempio, utilizzando PhPass). R è quindi considerata una seconda password. Vantaggio: anche se la prima password non è buona (ad es., "Password1"), R è un'ottima password. Il database in realtà non può essere incrinato, quindi non dovrebbe essere una preoccupazione. (Sono stato inutilmente preoccupato, penso.)

+0

ho aggiunto un modo per bloccare il cookie al browser: Prima dell'hashing, concatenato ciò che chiamo R con l'agente utente + alcune proprietà dello schermo (DPI, larghezza, altezza, ecc.). Naturalmente, nessuna delle proprietà concatenate è memorizzata nel cookie, solo R lo è. Quindi, se il cracker ottiene R, lui/lei dovrebbe essere eseguito dal browser su un computer con le stesse proprietà. Non perfetto, ma rende molto più difficile la creazione dei dati dei cookie. Penso che il mio approccio sia migliore di quello che fanno molte persone, con hash con IP. Gli IP cambiano molto più spesso rispetto alle versioni del browser o ai monitor dei computer. –

risposta

1

Penso che tu abbia un piano piuttosto buono qui. In generale, il cookie dovrebbe essere completamente casuale e non dovrebbe contenere alcun dato utilizzato dal server. L'idea è che tutto ciò che è controllato dal cliente possa essere manomesso. Anche quando il valore è crittografato, ho visto gli hacker manipolare bit e ottenere i dati manomessi per decrittografarli su un ID di un altro utente (sì, quello mi ha spaventato un po '). Detto questo penso che il suggerimento di Charlie Miller sia soddisfacente, perché 128 bit è una buona quantità di entropia. Personalmente, andrei con byte completamente casuali per un cookie tale che nessun modello emerga in alcun modo.

La nostra ultima implementazione di un cookie di verifica era un valore a 256 bit completamente casuale stampato in ascii-hex mappato a un ID utente e alle informazioni di sessione nel nostro DB. Abbiamo mantenuto le informazioni sulla sessione crittografate con una chiave segreta, quindi se un utente malintenzionato SQL ha iniettato il nostro DB, sarebbero tutte informazioni inutili crittografate. Naturalmente un compromesso totale della macchina DB fornirebbe l'accesso alla chiave, ma è molto più difficile da fare perché coinvolge più exploit e pivot.

Un buon consiglio è di non pensarci troppo. Ci siamo imbattuti in problemi di implementazione perché abbiamo "over-engineered", e alla fine non abbiamo avuto comunque molto vantaggio sulla sicurezza. Un semplice numero casuale è il meglio che puoi fare (purché sia ​​sufficientemente lungo da fornire sufficiente entropia).