Come eseguire l'autenticazione senza stato (senza sessione) e senza cookie?


107

Bob usa un'applicazione web per ottenere qualcosa. E:

  • Il suo browser è a dieta, quindi non supporta i cookie .
  • L'applicazione web è popolare, si occupa di molti utenti in un dato momento e deve essere scalabile bene. Fintanto che mantenere la sessione imporrebbe un limite al numero di connessioni simultanee e, ovviamente, comporterà una riduzione delle prestazioni non trascurabile , potremmo voler avere un sistema senza sessione :)

Alcune note importanti:

  • abbiamo la sicurezza dei trasporti ( HTTPS e i suoi migliori amici);
  • dietro le quinte, l'applicazione web delega molte operazioni a servizi esterni , per conto dell'utente corrente (quei sistemi riconoscono Bob come uno dei loro utenti) - questo significa che dobbiamo inoltrare loro le credenziali di Bob .

Ora, come autentichiamo Bob (su ogni richiesta)? Quale sarebbe un modo ragionevole per implementare una cosa del genere?

  • giocare a tennis con le credenziali tramite campi nascosti da modulo HTML ... la pallina contiene le credenziali ( username e password ) e le due racchette sono rispettivamente il browser e l'applicazione web. In altre parole, possiamo trasportare i dati avanti e indietro tramite i campi del modulo anziché tramite i cookie. Ad ogni richiesta web, il browser pubblica le credenziali. Tuttavia, nel caso di un'applicazione a pagina singola , potrebbe sembrare di giocare a squash contro un muro di gomma, invece di giocare a tennis , poiché il modulo web contenente le credenziali potrebbe essere mantenuto in vita per l'intera vita della pagina web (e il server sarà configurato per non restituire le credenziali).
  • memorizzare il nome utente e la password nel contesto della pagina - variabili JavaScript ecc. Pagina singola richiesta qui, IMHO.
  • autenticazione basata su token crittografati. In questo caso, l'azione di accesso comporterebbe la generazione di un token di sicurezza crittografato (nome utente + password + qualcos'altro). Questo token verrà restituito al client e le richieste imminenti saranno accompagnate dal token. Questo ha senso? Abbiamo già HTTPS ...
  • altri...
  • ultima risorsa: non farlo, memorizza le credenziali nella sessione! La sessione è buona. Con o senza biscotti.

Ti viene in mente qualche problema di sicurezza / web in merito a qualche idea precedentemente descritta? Per esempio,

  • timeout : possiamo mantenere un timestamp , insieme alle credenziali (time-stamp = l'ora in cui Bob ha inserito le sue credenziali). Ad esempio, quando NOW - timestamp> soglia , potremmo rifiutare la richiesta.
  • Protezione cross-site scripting : non dovrebbe essere diverso in alcun modo, giusto?

Grazie mille per aver dedicato del tempo alla lettura di questo :)


1
Puoi aggiungere un token a ogni URL. ASP.NET ha una modalità (legacy) per farlo. Ciò dimostra che può funzionare.
usr

1
Dove sono tutti? :)
turdus-merula

2
Penso che tu abbia una buona idea delle opzioni disponibili. Fidati del tuo ragionamento e decidi tu stesso.
usr

un plugin come Silverlight of Flash è un'opzione?
Giu

@usr non è sicuro che sia una buona idea come se un hacker raggiungesse i tuoi log di websever potesse rubare il tuo token e accedere al tuo sistema.
GibboK

Risposte:


74

Ah, adoro queste domande: mantenere una sessione senza una sessione.

Ho visto diversi modi per farlo durante i miei stint durante le valutazioni delle applicazioni. Uno dei modi popolari è il modo di giocare a tennis che hai menzionato, inviando il nome utente e la password in ogni richiesta per autenticare l'utente. Questo, a mio avviso, non è sicuro, soprattutto se l'applicazione non è a pagina singola. Inoltre non è scalabile, soprattutto se desideri aggiungere l'autorizzazione alla tua app oltre all'autenticazione in futuro (anche se immagino che potresti creare qualcosa anche in base agli accessi)

Un meccanismo popolare, sebbene non completamente stateless (supponendo che tu abbia l'esecuzione di JavaScript) è l'incorporamento del cookie di sessione in JavaScript. Il ragazzo della sicurezza dentro di me sta urlando per questo, ma potrebbe effettivamente funzionare - ogni richiesta ha unX-Authentication-Tokenheader o qualcosa del genere, e lo mappi su un database, un archivio di file in memoria, ecc. sul back-end per convalidare l'utente. Questo token può avere un timeout di qualsiasi tempo specificato e, se scade, l'utente deve accedere di nuovo. È abbastanza scalabile: se lo si memorizza in un database, viene eseguita la sua unica istruzione SQL e con gli indici corretti, l'esecuzione dovrebbe richiedere pochissimo tempo, anche con più utenti simultanei. I test di carico qui sarebbero sicuramente d'aiuto. Se leggo correttamente la domanda, questo sarebbe il tuo meccanismo di token crittografato, anche se suggerirei vivamente di utilizzare un token crittograficamente casuale di 32 caratteri, invece di utilizzare una combinazione di nome utente + password + qualsiasi altra cosa - in questo modo, rimane imprevedibile, ma puoi comunque associarlo con l'ID utente o qualcosa di simile.

Qualunque cosa tu finisca per utilizzare, assicurati che ti venga inviato in modo sicuro. HTTPS ti protegge attraverso il cavo, ma non ti protegge se perdi il token di sessione tramite l'URL (o peggio, le credenziali tramite l'URL). Suggerirei di utilizzare un'intestazione o, se non è fattibile, di inviare il token ogni volta tramite una richiesta POST (ciò significherebbe un campo modulo nascosto nel browser dell'utente). L'ultimo approccio di utilizzare una richiesta POST dovrebbe utilizzare le difese CSRF, solo nel caso, anche se sospetto che l'utilizzo del token stesso potrebbe essere una sorta di difesa CSRF.

Ultimo, ma non meno importante, assicurati di avere un meccanismo nel back-end per eliminare i token scaduti. Questa è stata la rovina di molte applicazioni in passato: un database in rapida crescita di token di autenticazione che sembra non scomparire mai. Se devi supportare più accessi utente, assicurati di limitare il numero o di avere un limite di tempo più breve su ogni token. Come ho detto prima, il test di carico potrebbe essere la risposta a questo.

Ci sono altri problemi di sicurezza a cui posso pensare, ma sono troppo ampi per essere affrontati in questa fase: se tieni a mente tutti i casi di utilizzo (e abuso), dovresti probabilmente essere in grado di eseguire un'implementazione abbastanza buona di questo sistema.


Non potresti fare quello che fa il framework di gioco e inviare un cookie firmato all'utente? Quindi quel cookie viene rimandato al server per ogni richiesta successiva?
j sarà il

8
> Il suo browser è a dieta, quindi non supporta i cookie.
Karthik Rangarajan

4
Qualcuno di questi suggerimenti è effettivamente senza stato / senza sessione ? Dei tuoi cinque paragrafi principali (a partire dall'edizione 2013-12-19 del post): il n. 1 è introduttivo, il n. 2 propone sessioni extra-kludgy Web2.0 ™, il n. 3 è solo ammonimenti, il n. 4 discute le implicazioni di statefulness , e # 5 è un vago outro ... come è stato accettato ?? È tangenzialmente informativo nella migliore delle ipotesi!
JamesTheAwesomeDude

1

Informazioni sull'opzione di accesso - Penso che di solito tu voglia supportare sessioni anche per gli ospiti.

Quindi, se vuoi imporre l'accesso, l'opzione del token crittografato potrebbe essere buona. Potrebbe essere buono anche per la sessione degli ospiti in qualche modo. In un'altra direzione, combinerei tra l'aggiunta del token all'URL e l'opzione tennis.

Tieni presente che l'invio di credenziali solo nell'URL potrebbe essere pericoloso. Ad esempio, potresti perdere il token tramite l'intestazione del referer HTTP o anche da qualcuno che controlla il tuo traffico o guarda il tuo computer.

Un'altra cosa, anche se potessi usare i cookie, ti consiglierei di aggiungere un token casuale o un verificatore casuale, per proteggerti dagli attacchi Cross Site Request Forgery (CSRF).


3
Una sessione è lo stato memorizzato sul server. La domanda richiede l'autenticazione senza stato.
Kwebble
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.