2015-12-01 34 views
14

Una società esterna ha eseguito alcuni test di penetrazione sull'applicazione ASP.NET MVC 5 su cui sto lavorando.Invalidate Old Session Cookie - Identità ASP.Net

Un problema che hanno sollevato è descritta di seguito

Un cookie legati con la gestione delle sessioni è chiamato AspNet.ApplicationCookie. Se inserito manualmente, l'applicazione autentica l'utente. Anche se l'utente si disconnette dall'applicazione, il cookie è ancora valido. Ciò significa che il vecchio cookie di sessione può essere utilizzato per un'autenticazione valida entro un periodo di tempo illimitato. Nel momento in cui viene inserito il vecchio valore, l'applicazione lo accetta e lo sostituisce con un cookie appena generato. Pertanto, se l'utente malintenzionato accede a uno dei cookie esistenti, verrà creata la sessione valida, con lo stesso accesso come in passato.

Stiamo utilizzando ASP.NEt Identity 2.2

Ecco la nostra azione di logout sul controller conto

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult LogOff() 
    { 
     AuthenticationManager.SignOut(); 
     return RedirectToAction("Login", "Account"); 
    } 

in startup.auth.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/Login"), 
      ExpireTimeSpan = TimeSpan.FromHours(24.0), 
      Provider = new CookieAuthenticationProvider 
      { 
       // Enables the application to validate the security stamp when the user logs in. 
       // This is a security feature which is used when you change a password or add an external login to your account. 
       OnValidateIdentity = SecurityStampValidator 
      .OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
       validateInterval: TimeSpan.FromMinutes(1.0), 
       regenerateIdentityCallback: (manager, user) => 
        user.GenerateUserIdentityAsync(manager), 
       getUserIdCallback: (id) => (Int32.Parse(id.GetUserId()))) 

      } 
     }); 

avrei pensavo che il framework si sarebbe preoccupato di invalidare un vecchio cookie di sessione ma di navigare attraverso il codice sorgente di Owin.Security che non appare.

Come si annulla il cookie di sessione al logout?

modifica su Jamie Dunstan 's Consiglio ho aggiunto AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); ma poi non ha fatto alcuna differenza. Posso ancora uscire dall'applicazione, clonare una richiesta precedentemente autenticata in Fiddler e farla accettare dall'applicazione.

Edit: Il mio metodo di disconnessione aggiornato

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> LogOff() 
    { 
     var user = await UserManager.FindByNameAsync(User.Identity.Name); 

     AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); 
     await UserManager.UpdateSecurityStampAsync(user.Id); 

     return RedirectToAction("Login", "Account"); 
    } 
+0

Hai provato a sostituire 'AuthenticationManager.Signout();' con 'AuthenticationManager.Signout (DefaultAuthenticationTypes.ApplicationCookie);'? Il signout senza parametri sembra essere un po 'incoerente. –

+0

Cheers. Fatto, ma posso ancora uscire dall'applicazione, e quindi clonare una richiesta precedentemente autenticata in Fiddler e averla accettata – MrBliz

+0

Ho anche rimosso l'Expiretimespan all'avvio.Auth. Nessuna differenza. – MrBliz

risposta

5

Assicurarsi di utilizzare AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie); come giustamente suggerito da Jamie.

Essere in grado di accedere nuovamente con lo stesso cookie è di progettazione. L'identità non crea sessioni interne per tenere traccia di tutti gli utenti loggati e se OWIN ottiene un cookie che colpisce tutte le caselle (cioè copie della sessione precedente), ti permetterà di accedere.

Se è ancora possibile effettuare il login dopo l'aggiornamento del timbro di sicurezza, molto probabilmente OWIN non può ottenere una sospensione di ApplicationUserManager. Assicurarsi di avere questa linea appena sopra la app.UseCookieAuthentication

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 

Oppure, se si utilizza DI prendere ApplicationUserManager da DI:

app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>()); 

riducono anche il validateInterval: TimeSpan.FromMinutes(30) di valore inferiore - di solito accontentarsi di paio di minuti. Questa è la frequenza con cui Identity confronta i valori in auth-cookie con i valori nel database. E quando viene eseguito il confronto, Identity rigenera il cookie per aggiornare i timestamp.

+1

Ed ecco un'altra domanda con quasi la stessa risposta: http://stackoverflow.com/a/34016721/809357 – trailmax

+0

Grazie, posso confermare tutto quanto sopra è a posto. Ho modificato il validateInterval per validateInterval: TimeSpan.FromMinutes (1.0). Posso fare una richiesta autenticata, disconnettermi, attendere 5 minuti e clonare quella richiesta e ancora essere autenticato. Stai dicendo che dovrebbe accadere in base alla progettazione? – MrBliz

+0

@MrBliz corretto - in base alla progettazione. A meno che tu non modifichi il vecchio Timbro di sicurezza, il cookie ti autenticherà. Cookie memorizza nome utente, userId, timbro di sicurezza, alcuni timestamp e bit di altre informazioni (ecco un po 'più informazioni: http://tech.trailmax.info/2014/08/aspnet-identity-cookie-format/). E i metodi 'SignOut()' semplicemente uccidono il cookie. Ma se lo stesso cookie viene riprodotto di nuovo, lo accetterà. Allo stesso modo in cui ti disconnetti da un browser, ma l'altro è ancora autenticato. Pertanto, se è necessario interrompere tutte le sessioni, è necessario aggiornare il timbro di sicurezza contemporaneamente alla disconnessione. – trailmax

0

risposta di Trailmax è a posto, ho pensato di aggiungere che se qualcuno sta cercando di fare questo, mentre utilizzando anche ASP.NET Boilerplate, il seguente è quello che ho usato per fare questo lavoro:

app.CreatePerOwinContext(() => IocManager.Instance.Resolve<UserManager>());

ho inizialmente avuto:

app.CreatePerOwinContext(() => IocManager.Instance.ResolveAsDisposable<UserManager>());

ed è non funzionava.

Problemi correlati