web-dev-qa-db-fra.com

Cookie d'ancienne session invalide - Identité ASP.Net

Une entreprise externe a effectué des tests de pénétration sur l'application ASP.NET MVC 5 sur laquelle je travaille.

Un problème qu'ils ont soulevé est décrit ci-dessous

Un cookie lié à la gestion de session est appelé AspNet.ApplicationCookie. Lorsqu'elle est entrée manuellement, l'application authentifie l'utilisateur. Même si l'utilisateur se déconnecte de l'application, le cookie est toujours valide. Cela signifie que l'ancien cookie de session peut être utilisé pour une authentification valide dans un délai illimité. Au moment où l'ancienne valeur est insérée, l'application l'accepte et la remplace par un cookie nouvellement généré. Par conséquent, si l'attaquant accède à l'un des cookies existants, la session valide sera créée, avec le même accès que par le passé.

Nous utilisons ASP.NEt Identity 2.2

Voici notre action de déconnexion sur le contrôleur de compte

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

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

            }
        });

J'aurais pensé que le framework aurait pris soin d'invalider un ancien cookie de session mais en parcourant le code source Owin.Security, il ne semble pas.

Comment invalider le cookie de session à la déconnexion?

éditez sur Jamie Dunstan les conseils que j'ai ajoutés AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); mais n'ont ensuite fait aucune différence. Je peux toujours me déconnecter de l'application, cloner une demande précédemment authentifiée dans Fiddler et la faire accepter par l'application.

Edit: Ma méthode de déconnexion mise à jour

 [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");
    }
23
MrBliz

Assurez-vous d'utiliser AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie); comme suggéré correctement par Jamie.

La possibilité de se connecter à nouveau avec le même cookie est de par leur conception. L'identité ne crée pas de sessions internes pour suivre tous les utilisateurs connectés et si OWIN obtient un cookie qui frappe toutes les cases (c'est-à-dire des copies de la session précédente), il vous permettra de vous connecter.

Si vous pouvez toujours vous connecter après la mise à jour du tampon de sécurité, OWIN ne pourra probablement pas obtenir ApplicationUserManager. Assurez-vous que cette ligne se trouve juste au-dessus du app.UseCookieAuthentication

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

Ou si vous utilisez DI, prenez ApplicationUserManager de DI:

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

Réduisez également la validateInterval: TimeSpan.FromMinutes(30) à une valeur inférieure - je me contente généralement de quelques minutes. Il s'agit de la fréquence à laquelle Identity compare les valeurs du cookie d'authentification aux valeurs de la base de données. Et lorsque la comparaison est terminée, Identity régénère le cookie pour mettre à jour les horodatages.

9
trailmax

La réponse de Trailmax est parfaite, j'ai pensé que j'ajouterais que si quelqu'un essaie de le faire tout en utilisant ASP.NET Boilerplate , voici ce que j'ai utilisé pour que cela fonctionne:

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

J'avais à l'origine:

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

et ne fonctionnait pas.

0
greggor01