Utilizzo dell'hash della password come ID di sessione?

8

Per un'app web client ricca, sul server ho bisogno di verificare che ogni chiamata provenga da un utente legalmente connesso. Ovviamente l'ID utente non è sufficiente, perché è facile da indovinare.

Ho un'idea di cui sono scettico, ma non riesco a pensare a ragioni razionali per non farlo.

Sta usando l'hash della password protetto con una funzione hashing sufficientemente strong (bcrypt?) un buon identificatore di sessione? È già in DB, è unico per ogni utente e non può essere indovinato facilmente. Sto utilizzando un canale sicuro (HTTPS) per tutte le comunicazioni tra client e server, quindi non devo preoccuparmi di intercettare l'identificatore di sessione.

Non mi interessa la scadenza della sessione, lo stato o l'accesso da due computer alla volta. L'app del server è abbastanza stateless. Tutto ciò di cui ho veramente bisogno è l'ID utente e alcuni mezzi extra di verifica che ha effettuato l'accesso correttamente.

    
posta Konrad Garus 30.06.2011 - 18:32
fonte

4 risposte

13

Un problema che potresti avere con questo tipo di configurazione è, da quello che hai detto, sembra che il token di sessione sia statico (cioè per un dato utente, non cambia mai, finché non cambiano la password). Pertanto, se un utente malintenzionato riesce ad accedere a un token per un determinato utente (trojan, keylogger, sniffing dei pacchetti (se SSL non viene utilizzato) ecc., Avrà accesso permanente all'applicazione.

Inoltre, devi essere più attento del solito per assicurarti che i token di sessione non vengano registrati da nessuna parte sul lato server in quanto sostanzialmente equivalenti alle password.

    
risposta data 30.06.2011 - 20:45
fonte
7

Non so quali librerie stai usando per scrivere la tua applicazione, ma la maggior parte fornisce una sorta di gestione delle sessioni.

L'implicazione dell'utilizzo di un hash per la password di un token di sessione non ti consentirà di distinguere una sessione da un'altra. E se due utenti avessero la stessa password? Sarai in grado di distinguere?

Inoltre, ti renderai vulnerabile agli attacchi di replay, a meno che tu non scelga di aggiungere alcuni dati casuali al token di sessione. Questo è necessario archiviare in una memoria persistente da qualche parte.

Quando sei già andato così lontano, dovresti scegliere di generare l'intero token di sessione, poiché hai già bisogno di una tabella di sessione.

Per un canale HTTPS, tutto può funzionare finché nessuno è in grado di leggere i cookie (ricorda solo i cookie https!) o indovinarli.

    
risposta data 30.06.2011 - 18:50
fonte
4

Un buon cookie di sessione antepone una scadenza ai dati serializzati e quindi antepone un HMAC della scadenza + i dati serializzati alla scadenza + i dati serializzati utilizzando la chiave segreta dell'applicazione.

message = serialize_to_bytes(session_data)
random = random_bytes(16)
expiration = unix_timestamp_as_16_bytes(now + 2 * 60 * 60 /*2 hours*/)
signable = random + expiration + message
signature = HMAC-SHA256(application_key, signable)
signed_message = signature + signable

Il signed_message non sarà cancellabile. Sarà soggetto a ripetizione dell'attacco per 2 ore. Se il cookie di sessione firmato viene violato nella finestra di 2 ore, la sessione potrebbe essere estesa all'infinito. Per fare meglio, dovresti trovare un buon piano per i nonces. In una grande applicazione con più server Web che servono i cookie di sessione, ciò richiederebbe un database centrale di nonces usati, che può essere poco pratico.

Assicurati di impostare il flag secure del cookie (in modo che venga inviato solo nelle richieste HTTPS) e il flag httponly (in modo che non sia disponibile direttamente in JavaScript).

Assicurati di utilizzare SSL sempre.

    
risposta data 27.07.2011 - 22:23
fonte
3

L'approccio proposto mi sembra un approccio inadeguato. Lascia che il framework web faccia la gestione della sessione per te. Numerosi framework Web forniranno già il supporto per l'autenticazione dell'utente e consentiranno, in una singola chiamata, di stabilire se vi è un utente connesso con la sessione della richiesta corrente. Basta usare quello. Tirare il tuo è pericoloso. Non capisco perché hai bisogno o vuoi eseguire un meccanismo speciale per questo.

    
risposta data 03.08.2011 - 09:09
fonte

Leggi altre domande sui tag