it-swarm.dev

È sicuro archiviare la password in HTML5 sessionStorage?

Sto cercando di migliorare l'esperienza dell'utente durante la registrazione non richiedendo all'utente di riscrivere la password se la convalida su altri campi fallisce. Esistono alcuni modi per implementarlo, ad esempio utilizzando il cookie di sessione e la memorizzazione di un hash della password sul lato server. Sto esplorando questa alternativa di archiviare temporaneamente la password utente sul lato client senza che il server ne tenga traccia. Questo metodo è fattibile? Quali sono i rischi?

16

In linea di principio, i valori archiviati in sessionStorage sono limitati allo stesso schema + nome host + porta univoca e, se il browser ha un'uscita pulita, questi valori devono essere eliminati alla fine della sessione. Tuttavia, secondo questo post può sopravvivere al riavvio del browser se l'utente sceglie di "ripristinare la sessione" dopo un arresto (il che significa che i suoi valori esistono anche nella memoria persistente fino a quando non vengono cancellati, quindi tieni in mente). Se ben implementato, direi che è abbastanza sicuro, soprattutto rispetto alla tua alternativa all'uso di un cookie (che presenta molte insidie ​​che non prenderei nemmeno in considerazione). Le specifiche del W3C affermano inoltre che l'archiviazione Web potrebbe effettivamente essere utilizzata per archiviare dati sensibili (sebbene non sia chiaro se tale pratica sia approvata o meno).

Per quanto riguarda i rischi, è semplicemente una questione di compromessi: stai rendendo il tuo sito un po 'più conveniente per i tuoi utenti, aumentando un po' la finestra di opportunità per la cattura della password (sia tramite una vulnerabilità XSS, di il valore che persiste nell'archiviazione persistente più a lungo del previsto o dall'utente che lascia il computer incustodito prima di terminare la registrazione). Idealmente, le password non dovrebbero mai lasciare la RAM, ma di solito non è pratico, quindi è necessario un compromesso. Consiglio solo di cancellare la password da sessionStorage non appena la registrazione ha esito positivo e di tenere d'occhio le vulnerabilità sulle implementazioni di sessionStorage che potrebbero eventualmente venire alla luce.

14
mgibsonbr

Suggerisco un altro approccio: invece di inviare il modulo al server, utilizzare un XMLHttpRequest per creare l'account. Se la convalida lato server non riesce, il modulo e tutto il suo contenuto sono ancora disponibili. Se ha esito positivo, reindirizzare alla pagina di destinazione.

Ciò richiede che JavaScript sia abilitato, ma è comunque possibile tornare alla normale presentazione del modulo. L'accesso a SessionStorage richiede comunque JavaScript.

8

Avrai difficoltà a decidere quale dei due valori archiviati utilizzare come password designata dall'utente (quella nella memoria locale o quella nel campo di input), se nessuno di essi è vuoto ma per qualche motivo differisce.

Questo può potenzialmente fornire un vettore di attacco di ingegneria sociale, in cui l'attaccante prepara una trappola aprendo il modulo di registrazione, riempiendo l'archiviazione locale/di sessione utilizzando il proprio codice e successivamente rimuovendo ogni traccia di esso (notifiche di errore di input) con un DOM o inserendo la password desiderata direttamente nell'archivio locale/di sessione (entrambi sono supportati su alcuni browser ed estremamente facili da eseguire), quindi chiedono in seguito alla vittima di registrarsi con il tuo sito Web e, bene, di usarla. Poiché il tuo codice può essere facilmente ispezionato/testato per vedere come gestisci tali casi, l'aggressore potrebbe farlo in modo leggermente diverso da quello che ho descritto (anche le iniezioni di script direttamente nell'archivio locale/della sessione non sono fuori questione, se in seguito elaborerai quel valore localmente sul modulo POST), ma con lo stesso effetto.

La vittima non sospetterà nulla finché non si disconnetterà e tenterà di riconnettersi. A seconda della persistenza della sessione dell'utente, questo processo di disconnessione e di accesso potrebbe non essere necessario e la vittima non l'avrebbe notata password non era quella immessa nel campo password, ma invece è stata utilizzata la password scelta dall'aggressore per creare il suo nuovo account.

Aghi da dire, l'attaccante ha appena ottenuto l'accesso all'account appena creato della vittima e a tutti i dati inseriti dalla vittima, anche se la vittima era cauta e si assicurava che non fosse coinvolto il surf sulle spalle.

Quindi, da asporto qui è che dovrai potenzialmente trattare con due posizioni diverse degli stessi dati di registrazione del sistema, che potrebbero per qualsiasi motivo differire e decidere quale utilizzare in un modo sicuro sia per il tuo sistema, sia per l'utente finale che si sta registrando. Questo potrebbe rivelarsi piuttosto complicato da fare correttamente, quindi sconsiglio.

Invece, assicurati piuttosto che il tuo modulo di registrazione sia servito tramite HTTPS, quindi riempi semplicemente il campo della password, poiché è stato inserito l'ultima volta nella richiesta dell'utente POST e se soddisfa i tuoi vincoli, anche se alcuni degli altri campi di input sono compilati in modo errato e il modulo deve essere ripubblicato.

6
TildalWave

Userei alcune comunicazioni intertab per distribuire la password invece di archiviare la password in qualsiasi archivio persistente (cookie, localstorage, ecc. Ci sono innumerevoli soluzioni, controlla evercookie). In questo modo la password rimarrà nel browser fino a quando non si chiude l'ultima scheda per il dominio effettivo.

Puoi fare comunicazioni intertab in modo sicuro con BroadcastChannel o SharedWorker o postMessage probabilmente lì sono altri metodi che non conosco, reinventano sempre la ruota. I primi due inviano i messaggi a ogni scheda, l'ultimo invia solo alle schede aperte dalla stessa scheda principale, quindi è in qualche modo restrittivo, ma supportato da più browser.

Se memorizzi le tue password nella memoria di js, devi impedire XSS con intestazioni speciali . E spesso. devi controllare il contenuto visualizzato per i tag HTML e devi sempre codificare JSON i dati che vuoi iniettare direttamente in javascript come variabile.

Il post di TildalWave è interessante, penso che questi metodi non siano vulnerabili a questo, perché la sincronizzazione è quasi istantanea e puoi anche sincronizzare login, logout, ecc.

Se decidi di utilizzare localstorage comunque, è meglio usare un ID utente, timeout e salt firmati anziché la password stessa. È possibile inviare le credenziali al server, che può verificarle e inviare nuovamente i dati con la firma. Possono essere memorizzati in un cookie o in qualsiasi altro archivio persistente desiderato. Questi token vengono talvolta utilizzati da REST se è presente un client browser, poiché questa soluzione è senza stato e dà comunque la sensazione di avere una sessione classica. A volte firmano ogni richiesta, non solo l'utente id per migliorare la sicurezza.

0
inf3rno