Invalidate Old Session Cookie - ASP.Net Identity
Asked Answered
I

3

31

An external company has done some penetration tests on the ASP.NET MVC 5 application i'm working on.

An issue that they raised is described below

A cookie linked with session Management is called AspNet.ApplicationCookie. When entered manually,the application authenticates the user. Even though the user logs out from the Application,the cookie is still valid. This means,the old session cookie can be used for a valid authentication within unlimited timeframe. In the moment the old value is inserted, the application accepts it and replaces it with a newly generated cookie. Therefore, if the attacker gains access to one of the existing cookies, the valid session will be created,with the same access as in the past.

We're using ASP.NEt Identity 2.2

Here's our logout action on the account 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())))

            }
        });

I would have thought that the framework would have taken care of invalidating an old session cookie but browsing through the Owin.Security source code it appears not.

How do i invalidate the session cookie on logout?

edit on Jamie Dunstan's Advice i've added AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie); but then has made no difference. I can still still log out of the application, clone a previously authenticated request in Fiddler, and have it accepted by the application.

Edit : My updated Logoff method

 [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");
    }
Its answered 1/12, 2015 at 12:42 Comment(5)
Have you tried replacing AuthenticationManager.Signout(); with AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie);? The parameterless signout appears to be a bit inconsistent.Inform
Cheers. Done, but i can still log out of the application, and then clone a previously authenticated request in fiddler and have it acceptedIts
I've also removed the Expiretimespan from startup.Auth. No difference.Its
The best idea I can come up with is to manually call UserManager.UpdateSecurityStampAsync(userId); after calling SignOut. Can you try this and see if it works?Inform
That did not work. Still able to use a previously authenticated request via fiddler after the user has logged out.Its
M
10

Make sure you use AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie); as correctly suggested by Jamie.

Being able to login with the same cookie again is by design. Identity does not create internal sessions to track all logged-in users and if OWIN gets cookie that hits all the boxes (i.e. copies from the previous session), it'll let you login.

If you still can login after the security stamp is updated, most likely OWIN can't get a hold of ApplicationUserManager. Make sure you have this line just above the app.UseCookieAuthentication

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

Or if you are using DI take ApplicationUserManager from DI:

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

Also reduce the validateInterval: TimeSpan.FromMinutes(30) to lower value - I usually settle for couple minutes. This is how often Identity compares values in auth-cookie to the values in the database. And when the comparison is done, Identity regenerates the cookie to update timestamps.

Morven answered 1/12, 2015 at 18:9 Comment(7)
And here is another question with almost the same answer: https://mcmap.net/q/471886/-asp-net-identity-2-invalidate-identity-difficultiesMorven
Thank you, i can confirm all the above is in place. I've changed the validateInterval to validateInterval: TimeSpan.FromMinutes(1.0). I can make an authernticated request, log out, wait for 5 minutes and clone that request and it still be authenticated. Are you saying that should happen by design?Its
@Its correct - by design. Unless you change the Security Stamp old cookie will authenticate you. Cookie stores username, userId, security stamp, some timestamps and bits of other information (here is a bit more info: tech.trailmax.info/2014/08/aspnet-identity-cookie-format). And SignOut() methods merely kills the cookie. But if the same cookie is replayed again, it will accept it. Same way you sign-out from one browser, but the other one is still authenticated. So if you need to kill all sessions, you need to update security stamp at the same time you sign-out.Morven
Thank you very much. Glad i tweeted you :)Its
@Its Bear in mind you can hit this issue: https://mcmap.net/q/471887/-can-39-t-logoff-identity-mvc-5-sometimes - it looks like a bug.Morven
@Morven - just stumbled across this answer as I have exactly the same issue as the OP. This answer has been very helpful in understanding that this is expected behavior, so thank you! However, I'm not totally clear on the conclusion and as to whether the OP's solution ever worked. "Unless you change the Security Stamp old cookie will authenticate you" - does this mean that by changing the Security Stamp we can put in place a workaround? I.e. will calling UserManager.UpdateSecurityStampAsync on sign-out along with a short validateInterval work? Logically, I think it should.Absorb
@PhilBellamy your thinking is correct. Shorten validateInterval and update security stamp.Morven
S
0

Trailmax's answer is spot on, I thought I would add that if someone is trying to do this while also using ASP.NET Boilerplate, the following is what I used to make this work:

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

I originally had:

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

and is wasn't working.

Scimitar answered 27/10, 2016 at 18:27 Comment(0)
L
0

you were on the right way. Indeed the easiest way is to update user SecurityStamp but normally executing it doesn't lead to success because actualy credentials aren't changed and it remains the same in db. Solution, try this:

private string NewSecurityStamp()
        {
            return Guid.NewGuid().ToString();
        }

private async Task RegenerateSecurityStamp(string userId)
    {
        var user = await _userManager.FindByIdAsync(userId);
            if (user != null)
            {
                user.SecurityStamp = NewSecurityStamp();
                await _userStore.UpdateAsync(user);
            }
    }

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> LogOff()
    {
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        await RegenerateSecurityStamp(User.Identity.GetUserId());
        return RedirectToAction("Login", "Account");
    }
Limoli answered 29/12, 2020 at 16:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.