Oggi ho notato qualcosa di inquietante durante il controllo i file di sessione in storage/framework/sessions
cartella creato da laravel 5.laravel - dati di sessione sopravvive log-out/log-in, anche per diversi utenti
Ecco cosa è successo:
- ho effettuato il login come utente a
- ho navigato a una pagina che memorizza variabile X nella sessione
- mi sono collegato fuori, ma non chiudere il browser.
- Il file di sessione in
storage/framework/sessions
era ancora lì e il cookie del browser era attivo. - Ho effettuato l'accesso come utente B.
- Il vecchio file di sessione in
storage/framework/sessions
è stato eliminato e un nuovo file di sessione era lì. - Ho esaminato il nuovo file di sessione: sorpresa! la variabile X è sopravvissuta alla disconnessione ed è ancora lì, accessibile per l'utente B!
conduce a problemi di sicurezza perché ora l'utente B ha accesso ai dati degli utenti A.
Durante il debug attraverso il codice sorgente laravel, ho scoperto che Session Store è non essere mai chiarito durante il logout/login processi. Solo le credenziali di accesso vengono rimosse nel metodo Illuminate\Auth\Guard::clearUserDataFromStorage()
, ma tutti gli attributi di sessione archivio sono ancora lì, e successivamente quando viene chiamato $kernel->terminate($request, $response);
, che a sua volta conduce a Illuminate\Session\Middleware\StartSession::terminate()
chiamando Store::save()
, che salva ciecamente $this->attributes
nella nuova sessione, ignorando il fatto che ora appartiene a un altro utente.
Da un lato, sembra logico - Laravel non ha ipotesi sui miei dati e se voglio che scadano insieme con l'autenticazione o meno. Ma sarebbe bello averlo documentato da qualche parte con una soluzione per collegare alcuni dati sensibili all'oggetto di autenticazione e scadere insieme ad esso.
Questo significa che io come programmatore sono responsabile per tutto spazzare via tutti i dati sensibili dalla sessione corrente in caso di nuove (o lo stesso) utente accede a.
Clearing il logout non sarebbe affidabile, perché l'utente potrebbe non fare mai clic sul collegamento Disconnettersi ma attendere che la sessione scada, il che per Laravel non cancella ancora la sessione.
Un'ultima cosa da tenere a mente: non dovrei cancellare la sessione troppo presto: c'è il token AntiForgery che deve essere presente, altrimenti il modulo di login fallirà sempre.
ho trovato un argomento del forum, che cerca anche di risolvere il problema in qualche modo simile:
http://laravel.io/forum/04-27-2014-how-to-expire-session-data
mi sono confuso da questo:
avevo un altro andare a oggi e realizzato ciò che il problema era: Session :: flush() non elimina i dati di sessione creati dall'app, come i dettagli del carrello acquisti
Se questo è vero, l'unico modo per liberarsi completamente della sessione sarebbe utilizzare PHP nativo session_unset()
e session_destroy()
ma non vorrei andare in quel modo - preferirei trovare una soluzione Laravel-ish più pulita, se possibile.
Come comunicare a Laravel che desidero rimuovere i miei vecchi dati di sessione insieme ai dati di autenticazione utente quando l'autenticazione scade o l'utente si disconnette?
Sì, questo dovrebbe funzionare quando l'utente si disconnette di proposito. Ma nel caso in cui se solo mantiene il browser aperto fino alla scadenza della sessione, dovrò chiamare manualmente quelle funzioni di dimenticanza e scarico. Sembra, non sono l'unico ad aver scoperto questo potenziale problema di sicurezza: https://github.com/laravel/framework/issues/8661 – JustAMartin
Aggiornamento della risposta. Questo risolve il problema per te? – MartinJH
Sì, se l'utente chiude il browser, funziona sempre correttamente e non ci sono problemi. Il problema è solo se l'utente se ne va e poi molto più tardi arriva un altro utente e accede - quindi sono presenti le vecchie variabili di sessione. Immagino, dovrò convivere con queste chiamate flush() durante il logout e l'accesso, mentre non c'è una soluzione integrata migliore in Laravel per specificare che non voglio che alcune variabili di sessione rimangano in vita dopo che la sessione è cambiata . – JustAMartin