2015-12-01 11 views
14

Ein externes Unternehmen hat einige Penetrationstests für die ASP.NET MVC 5-Anwendung ausgeführt, an der ich gerade arbeite.Old Session-Cookie ungültig machen - ASP.Net Identity

Ein Thema, das sie angehoben unter

Ein Cookie mit Session-Management verknüpft beschrieben wird AspNet.ApplicationCookie genannt. Wenn sie manuell eingegeben wird, authentifiziert die Anwendung den Benutzer. Obwohl sich der Benutzer von der Anwendung abmeldet, ist der Cookie weiterhin gültig. Das heißt, das alte Session-Cookie kann für eine gültige Authentifizierung innerhalb unbegrenzter Zeit verwendet werden. In dem Moment, in dem der alte Wert eingefügt wird, akzeptiert die Anwendung sie und ersetzt sie durch ein neu erzeugtes Cookie. Wenn der Angreifer Zugriff auf eines der vorhandenen Cookies erhält, wird daher die gültige Sitzung mit demselben Zugriff wie in der Vergangenheit erstellt.

Wir verwenden ASP.NEt Identität 2.2

Hier ist unsere Abmeldung auf dem Konto Controller

[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()))) 

      } 
     }); 

Ich hätte Ich dachte, dass das Framework dafür gesorgt hätte, ein altes Session-Cookie ungültig zu machen, aber das Browsen durch den Quellcode von Owin.Security scheint nicht der Fall zu sein.

Wie kann ich den Sitzungscookie beim Abmelden ungültig machen?

bearbeiten auf Jamie Dunstan 's Beratung habe ich AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); hinzugefügt, aber dann hat es keinen Unterschied gemacht. Ich kann mich immer noch von der Anwendung abmelden, eine zuvor authentifizierte Anfrage in Fiddler klonen und sie von der Anwendung akzeptieren lassen.

Edit: Meine aktualisiert Abmelde Methode

[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

Haben Sie versucht, 'AuthenticationManager.Signout();' durch 'AuthenticationManager.Signout (DefaultAuthenticationTypes.ApplicationCookie);'? Das parameterlose Abmelden scheint etwas inkonsistent zu sein. –

+0

Prost. Fertig, aber ich kann mich immer noch von der Anwendung abmelden, und dann eine zuvor authentifizierte Anfrage in Fiddler klonen und es akzeptiert haben – MrBliz

+0

Ich habe auch die Expiretimespan von startup.Auth entfernt. Kein Unterschied. – MrBliz

Antwort

5

Stellen Sie sicher, AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie); als richtig vorgeschlagen von Jamie verwenden.

Die Möglichkeit, sich erneut mit demselben Cookie anzumelden, ist von Entwurf. Identity erstellt keine internen Sitzungen, um alle angemeldeten Benutzer zu verfolgen, und wenn OWIN einen Cookie erhält, der alle Felder berührt (d. H. Kopien der vorherigen Sitzung), können Sie sich anmelden.

Wenn Sie sich immer noch anmelden können, nachdem der Sicherheitsstempel aktualisiert wurde, kann OWIN höchstwahrscheinlich ApplicationUserManager nicht erreichen. Stellen Sie sicher, dass Sie diese Zeile haben gerade über die app.UseCookieAuthentication

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

Oder wenn Sie DI ApplicationUserManager von DI nehmen verwenden:

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

Auch die validateInterval: TimeSpan.FromMinutes(30) reduzieren Wert zu senken - ich in der Regel für ein paar Minuten absetzen. So oft vergleicht Identity die Werte in auth-cookie mit den Werten in der Datenbank. Und wenn der Vergleich abgeschlossen ist, regeneriert Identity das Cookie, um Zeitstempel zu aktualisieren.

+1

Und hier ist eine andere Frage mit fast der gleichen Antwort: http://stackoverflow.com/a/34016721/809357 – trailmax

+0

Vielen Dank, ich kann bestätigen, dass alle oben genannten vorhanden ist. Ich habe validateInterval in validateInterval geändert: TimeSpan.FromMinutes (1.0). Ich kann eine authentifizierte Anfrage machen, mich abmelden, 5 Minuten warten und diese Anfrage klonen und sie wird noch authentifiziert. Willst du sagen, dass das von vornherein passieren sollte? – MrBliz

+0

@MrBliz richtig - von Design. Wenn Sie den Sicherheitsstempel nicht ändern, wird Sie der alte Cookie authentifizieren. Cookie speichert Benutzernamen, userId, Sicherheitsstempel, einige Zeitstempel und Bits anderer Informationen (hier ist ein bisschen mehr Info: http://tech.trailmax.info/2014/08/aspnet-identity-cookie-format/). Und 'SignOut()' Methoden töten nur den Cookie. Wenn derselbe Cookie erneut abgespielt wird, wird er akzeptiert. Genauso wie Sie sich von einem Browser abmelden, aber der andere noch authentifiziert ist. Wenn Sie also alle Sitzungen beenden müssen, müssen Sie den Sicherheitsstempel bei der Abmeldung aktualisieren. – trailmax

0

Trailmax Antwort ist genau das Richtige, ich dachte, ich würde hinzufügen, dass, wenn jemand diese während versucht auch ASP.NET Boilerplate mit tun, die folgende ist, was ich diese Arbeit machen verwendet:

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

ich ursprünglich hatte:

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

und arbeitet nicht.

Verwandte Themen