it-swarm.dev

Demistificazione dell'autenticazione Web (cookie di sessione stateless)

Attualmente sto cercando protocolli di autenticazione utente per un sito Web che sto sviluppando. Vorrei creare un cookie di autenticazione in modo che gli utenti possano rimanere connessi tra le pagine.

Ecco il mio primo bash:

cookie = user_id|expiry_date|HMAC(user_id|expiry_date, k)

Dove k è HMAC(user_id|expiry_date, sk) e sk è una chiave a 256 bit nota solo al server. HMAC è un hash SHA-256. Nota che '|' è un separatore, non solo concatenazione.

Questo appare così in PHP (Nota, questa domanda è indipendente dalla lingua, PHP è solo un esempio):

$key = hash_hmac('sha256', $user_id . '|' . $expiry_time, SECRET_KEY);
$digest = hash_hmac('sha256', $user_id . '|' . $expiry_time, $key);
$cookie = $user_id . '|' . $expiry_time . '|' . $digest;

Vedo che è vulnerabile agli Replay Attacks come indicato in A Secure Cookie Protocol, ma dovrebbe essere resistente agli attacchi di volume e allo splicing crittografico.

LA DOMANDA: Sono sulla linea giusta qui, o c'è una grande vulnerabilità che mi sono perso? Esiste un modo per difendersi da Replay Attacks che funziona con indirizzi IP assegnati dinamicamente e non utilizza sessioni? Non voglio archiviare nulla sul lato server per fare questo lavoro.

Inoltre, non sto pianificando o realizzando il mio. Lo sto chiedendo per giudicare meglio quale soluzione dovrei scegliere. Quindi nessuna risposta "Usa solo la soluzione X" non risponde senza una sorta di spiegazione.

APPUNTI

Il materiale più recente che ho letto:
Dos e cosa non fare dell'autenticazione client sul Web aka Fu et al.
( https://pdos.csail.mit.edu/papers/webauth:sec10.pdf )

A Secure Cookie Protocol aka Liu et al.
( http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf )
che si espande sul metodo precedente

Cookie di sessione senza stato induriti
( http://www.lightbluetouchpaper.org/2008/05/16/hardened-stateless-session-cookies/ )
che si espande anche con il metodo precedente.

Poiché l'argomento è estremamente complicato, sto solo cercando risposte da esperti di sicurezza con esperienza nel mondo reale nella creazione e nella rottura di schemi di autenticazione.

42
Joony

Gli "attacchi di replay" non si applicano ai cookie, perché un cookie è per definizione qualcosa che deve essere riprodotto: il browser dell'utente restituisce lo stesso valore del cookie, ed è così che il tuo il server sa che è lo stesso utente.

Quello che vuoi evitare è qualcuno che spia sulla linea, osservando il valore del cookie e quindi inviando lo stesso cookie sulle proprie connessioni. L'unica soluzione pratica nota è quella di eseguire l'intero protocollo all'interno di un tunnel che garantisca la riservatezza e l'integrità dei dati in transito, noto anche come "SSL" (aka HTTPS ).

Quindi ci sono due modi per generare e verificare i valori dei cookie sul server:

  • Puoi semplicemente generare un valore casuale di dimensioni sufficienti (ovvero circa 16 byte), in modo che sia altamente improbabile per un attaccante indovinare il valore per pura fortuna. Il server ricorda per ogni utente il suo "token di sessione" corrente, come una colonna aggiuntiva nel database "utenti".

  • Il token viene prodotto come valore imperdonabile calcolato in modo deterministico dall'identificatore utente. Questo è quello che fai, e questo è un concetto ragionevole. Fondamentalmente, invece di memorizzare un po 'di stato in più sul server, lo scarichi sul client e usi un MAC con una chiave sul lato server in modo che i client impossibile creare valori di cookie "validi".

Il codice descrive due chiamate HMAC nidificate, che sono strane e ingiustificate. È sufficiente una chiamata. La costruzione generica è che un cookie contiene un valore v e un MAC m tale che v codifica lo stato desiderato da memorizzare nel client e m viene calcolato su v. Lo stato che desideri memorizzare, nel tuo caso, è: "questo client ha ID utente i e ha effettuato l'accesso al tempo t". Puoi usare qualunque codifica desideri a condizione che tu possa decodificarla in modo inequivocabile.

Per riassumere: la produzione di valori di cookie con un MAC è un modo valido di gestire la sessione, e HMAC/SHA-256 è buono per questo. Ma devi pensarlo come ottimizzazione: memorizzi i valori nel client per evitare di memorizzarli sul server. Ciò ha la sfortunata conseguenza che il client può dimenticare i dati fuori dal tuo controllo (il client può distruggere il cookie) o può fare dei time warp (il client può cambiare il valore memorizzato nel suo browser con un valore di cookie più vecchio - un problema che è mitigato dall'inclusione delle date nei cookie, sotto il controllo del MAC).

Se riesci a mantenere il lato server di stato e ad utilizzare solo valori di cookie casuali, fallo: è più semplice e offre un maggiore controllo al server.

35
Thomas Pornin

Il primo passo per proteggere qualsiasi applicazione web sta usando SSL. Ciò mantiene confidenziale il tuo cookie, previene gli attacchi di replay, assicura che l'utente stia parlando con il server giusto, previene MitM, impedisce agli aggressori di modificare i dati sulla rete ...

Quindi imposta il flag secure sul cookie, quindi viene inviato solo su SSL. L'impostazione del flag http-only, Per impedire a JavaScript di leggerlo, non fa male.

Infine riguardo al tuo schema di cookie:

  • L'HMAC nidificato non ti guadagna nulla. Basta andare con user_id|expiry_date|HMAC(user_id|expiry_date, SECRET_KEY)
  • Cambia SECRET_KEY Regolarmente
  • Il user_id Non deve mai cambiare. vale a dire utilizzare l'id_utente numerico, non il nome utente o l'e-mail
  • user_idexpiry_date Non dovrebbero mai contenere un | Per garantire una chiara separazione del dominio
  • Se sei paranoico, usa un server di accesso specializzato, che firma il cookie invece di MACing. Quindi il server di accesso è l'unico server che ha la chiave richiesta per creare i cookie, i normali server web possono solo validarlo. => riduce la superficie di attacco
  • Il server può creare cookie validi per qualsiasi utente. Questo potrebbe essere indesiderabile.
13
CodesInChaos

Innanzitutto:

Non inventare i tuoi protocolli di sicurezza. È molto probabile che tu sbagli.

Ora è fuori mano, diamo un'occhiata a questo. Se riesco a ottenere HMAC(userid|expiry_date, k), senza accedere o essermi autenticato come quell'utente, ho rotto la sicurezza di questo sistema. Ciò si estende a tutti i tipi di problemi, come attacchi di fissazione di sessioni o di dirottamento di sessioni (spesso causati dal non utilizzo errato o non corretto di SSL/TLS).

Quando controlli il cookie di sessione, stai perdendo informazioni dai canali laterali di temporizzazione? Stai sicuramente usando HMAC correttamente? Hai detto che il tuo HMAC è SHA-256, intendi davvero HMAC-SHA-256? Perché passare attraverso una complicata procedura HMAC, quando potresti semplicemente generare una stringa casuale e associarla a un utente sul server (ad esempio in un database)? Perché non usare semplicemente user_id|expiry_date|HMAC-SHA-256(user_id|expiry_date, sk) (dove | È la concatenazione, non il carattere letterale di pipe)?

Per quanto riguarda la difesa dagli attacchi replay in un ambiente basato sul web, esaminare progetto CSRFGuard di OWASP . Non sarai in grado di integrarlo direttamente, ma potrebbe esserci un PHP equivalente da qualche parte. È tutto per moot se il tuo sito è vulnerabile agli attacchi XSS, comunque.

La sicurezza dovrebbe essere tramandata a un framework rispettato, testato in battaglia, non fatto ad hoc

Modifica, una breve parola sugli attacchi di fissazione della sessione:

Ho ipotizzato che se non stai consegnando la sicurezza a un framework ben collaudato, sei probabilmente vulnerabile. Dovrai sostanzialmente verificare che stai emettendo una chiave di sessione distinta quando l'utente esegue l'autenticazione (ovvero diverso da quello con cui l'utente ha iniziato). Con la strategia di cui sopra, user_id|expiry_date|HMAC(user_id|expiry_date, k) non cambierebbe quando l'utente si autentica, rendendolo vulnerabile a un attacco di fissazione di sessione.

8
Tinned_Tuna

Dato che l'argomento è estremamente complicato, sto solo cercando risposte da esperti di sicurezza con esperienza nel mondo reale nella creazione e nella rottura di schemi di autenticazione.

Hai ragione sul fatto che l'argomento è estremamente complicato.

Vai con le funzioni di sessione fornite dal tuo framework e non provare a creare il tuo. Se stai usando plain PHP invece di un framework ... shudders.

3
user10211