it-swarm-eu.dev

https security - la password deve essere hash lato server o lato client?

Sto creando un'applicazione Web che richiede agli utenti di accedere. Tutta la comunicazione passa attraverso https. Sto usando bcrypt per hash password.

Sto affrontando un dilemma: pensavo che fosse più sicuro creare un hash password lato client (usando JavaScript) e poi confrontarlo con l'hash nel lato server DB. Ma non sono sicuro che sia meglio che inviare una password in chiaro su https e poi cancellarla sul lato server.

Il mio ragionamento è che se un utente malintenzionato è in grado di intercettare il traffico https (= leggi la password in chiaro) può ad esempio anche modificare il JavaScript in modo da inviare la password in chiaro accanto a quella con l'hash - dove può intercettarla.

Il motivo contro hashing lato client è semplicemente la facilità d'uso. Se eseguo il hash sul lato client, devo utilizzare due librerie separate per l'hash. Questo non è un problema insormontabile, ma è un fastidio.

C'è un vantaggio in termini di sicurezza nell'utilizzo dell'hashing lato client? Perché?

Allora dovrei usare anche la risposta alla sfida?

AGGIORNAMENTO: ciò che mi interessa di più è questo: queste tecniche (hashing lato client, richiesta-risposta) aggiungono un significativo guadagno di sicurezza nel caso in cui venga utilizzato https? Se è così, perché?

116
johndodo

Se si esegue l'hash sul lato client, la password con hash diventa la password effettiva (con l'algoritmo di hashing che non è altro che un mezzo per convertire un posseduto dall'utente mnemonico nella password effettiva).

Ciò significa che memorizzerai la password completa "testo semplice" (l'hash) nel database e, in primo luogo, avrai perso tutti i vantaggi dell'hash.

Se decidi di seguire questa strada, potresti anche rinunciare a qualsiasi hashing e semplicemente trasmettere e memorizzare la password non elaborata dell'utente (che, per inciso, non consiglierei in particolare).

124
Nicole Calinoiu

L'hash sul client ha senso solo se non ti fidi del server in qualche modo e non vuoi mostrargli la password "effettiva" (quella che l'utente umano ricorda). Perché non dovresti voler mostrare la password proprio sul sito su cui tale password ha qualche utilità? Perché hai riutilizzato la password altrove ! Ora che di solito è male, ma esiste una versione relativamente sicura che si incarna in una miriade di estensioni del browser o bookmarklet come questo oppure quello (non garantisco la loro qualità). Si tratta di strumenti in cui l'utente umano ricorda una "password principale", da cui viene generata una password specifica del sito, utilizzando il nome del dominio del sito come una sorta di salt, in modo che due siti distinti ottengano password distinte.

Mentre questo scenario ha senso, farlo con Javascript inviato dal server stesso no. In effetti, il punto di hashing del lato client della password è che il server è potenzialmente ostile (ad esempio, sovvertito da un utente malintenzionato), e quindi il codice Javascript inviato da quel server è, almeno, sospetto. Non vuoi inserire la tua preziosa password in alcuni Javascript ostili ...


Un altro caso di hashing lato client è circa hashing lento. Poiché le password sono, per definizione, deboli, si desidera contrastare attacchi del dizionario . Supponi che il cattivo abbia una copia del database del server e "tenterà le password" sui propri computer (vedi questo post sul blog per qualche discussione al riguardo). Per rallentare l'avversario, si impiega un processo di hashing intrinsecamente lento (come bcrypt ), ma questo rallenterà l'elaborazione per tutti, incluso il server. Per aiutare il server, potresti voler scaricare parte del lavoro sul client, quindi esegui almeno una parte di esso in un codice Javascript in esecuzione nel browser del client ...

Sfortunatamente, Javascript è terribilmente lento in questo tipo di lavoro (in genere da 20 a 100 volte più lento del codice C decente) e il sistema client non sarà in grado di contribuire in modo sostanziale allo sforzo di hashing. L'idea è valida ma dovrà attendere una migliore tecnologia (avrebbe funzionato con un client Java, tuttavia: con una JVM decente, ottimizzata Java è circa 2 o 4 volte più lento del codice C ottimizzato, per un processo di hashing).


Per riassumere, non c'è davvero un buon caso per eseguire l'hash della password sul lato client, dal codice Javascript inviato dal server stesso. Basta inviare la password "così com'è" al server attraverso un tunnel HTTPS (la pagina di accesso, l'URL di destinazione del modulo e qualunque pagina siano protetti dalla password, devono tutto essere offerto su SSL, altrimenti hai problemi di sicurezza più urgenti rispetto all'uso delle password).

32
Thomas Pornin

Trovo che tutte le tue preoccupazioni siano valide, ma la mia raccomandazione sarebbe di farlo sul lato server.

C'è sempre una possibilità abbastanza grande che un utente lasci il proprio terminale sbloccato, consentendo la manipolazione. E anche; se la tua logica di hashing è lato client la stai esponendo.

Un'altra opzione sarebbe quella di generare le password lato server; quindi non stai inviando una password in chiaro. Ma dovrai comunque comunicare la password all'utente. E poiché la maggior parte degli utenti continua a non utilizzare la posta elettronica crittografata, la considero meno sicura.

Ho visto soluzioni per inviare password attraverso un tunnel crittografato a un cellulare; ma dubito che la sicurezza sia migliore dell'SSL. Forse qualcuno potrebbe provare/confutare questo?

11
rmorero

L'hashing sul lato server è importante come hanno indicato tutte le altre risposte, ma vorrei aggiungere che hashing lato client sarebbe una bella funzionalità di sicurezza in aggiunta all'hash lato server.

L'hash lato client presenta vantaggi nei seguenti scenari:

  1. Protegge la password dell'utente quando il server è compromesso. Cioè se il client non è compromesso, ma lo è il server, se il client esegue l'hashing della password, il server potrebbe comunque ottenere l'accesso a un sistema, ma hai protetto la password dell'utente che è importante se la utilizza altrove.
  2. Protegge la password dell'utente quando pensa che si stiano accedendo a un server ma che stiano davvero accedendo a un altro (errore utente). Ad esempio, se ho due conti bancari e digito accidentalmente una password della mia banca nel sito Web della banca errato, se la banca ha l'hash sul lato client quella banca non conoscerebbe la password della mia altra banca. Penso che sarebbe una cosa "educata" fare l'hash lato client in modo che la loro password in chiaro non venga mai trasmessa via cavo.

Principalmente mostra rispetto per la password dell'utente. L'utente sta condividendo un segreto che potrebbe non essere esclusivo del tuo software, quindi se rispetti quel segreto, dovresti fare tutto il possibile per proteggerlo.

10
Samuel

Se ci si trova in un tunnel HTTPS, la password o l'hash devono essere protetti dalla sorveglianza Ethernet.

Sul lato client forse potresti salare l'hash con un ID di sessione.
Questo potrebbe essere più difficile da simulare per JavaScript dannoso.

2
bua

Potresti fare entrambe le cose, l'hash sul client quindi se l'attaccante riesce a superare la sicurezza https non sarà in grado di vedere la password in chiaro. Quindi esegui nuovamente l'hash sul server, quindi se l'attaccante ottiene le password archiviate nel server non può semplicemente inviarle al server e ottenere l'accesso alla password.

1
nat that

Hashing della password lato client richiederà Javascript. Alcune persone disabilitano Javascript sul proprio browser. Devi gestire questo scenario.

Ho visto il software del forum che esegue l'hash della password sul lato client e invia l'hash all'accesso se possibile, altrimenti la password viene inviata in chiaro. Quindi funziona in entrambe le situazioni.

L'invio della password in chiaro non è un grosso problema se si utilizzerà https. Idealmente, il tuo server dovrebbe quindi rifiutare di pubblicare le pagine in http in modo da evitare man in the middle attack. Il ragionamento è: un utente malintenzionato può "forzare" il downgrade forzato della connessione da HTTPS a http e iniziare a sniffare il traffico (ad esempio con uno strumento come SSL Strip).

1
Anonymous

La risposta accettata di @ Nicole Calinoiu è ovviamente corretta ma forse è difficile da capire all'inizio.

Il punto è che la password deve essere sottoposta a hash sul server in modo che la persona malintenzionata non possa utilizzare gli hash che ha violato dal database dal server per ottenere l'accesso al proprio account o dati.

Come già detto se l'hash sul lato client e il back-end lo supporta, allora l'hash diventa la tua password e se l'hash viene rubato tramite un hack, l'hacker ha la password.

@ Thomas Pornin la risposta ha anche fornito un ottimo punto per cui vorresti inserire la password sul client, ma la cosa che descrive nella sua prima storia può essere fatta solo se il back-end del server supporta la gestione delle password con hash (cioè non hash la password se già con hash, ma che qualcuno cerca di supportare qualcosa del genere è altamente improbabile ), che il più delle volte non sarà il caso immagino. La seconda storia di lui è molto buona.

0
Ini