Cookie replay attacks in ASP.NET when using forms authentication

Microsoft ASP.NET 4.5 and earlier versions contain a weakness in the Forms Authentication functionality whereby user sessions are not properly terminated when a user logs out of the session. As a result, users are vulnerable to session hijacking even after logging out of the web application.

This weakness isn't new. There exists an article on Microsofts Knowledge Base that explains exactly this issue. So why is it important to mention it here again? Because the above KB-article was written for ASP.NET 2! The original KB publication date is unknown, but the revision information show that the KB-article was last updated in May 2007! This means that this issue in ASP.NET is already known for more than 7 years and it has survived several major ASP.NET versions.

Why is it important?

Many developers around the world rely on development frameworks to offer standardized functionality, such as providing safe session management. Developers expect that when an end-user clicks on the logout button, and when the server executes the FormsAuthentication.SignOut method on the server-side that the user's session is properly terminated and destroyed so that the user is effectively logged out. The latter is however not the case. Even after issuing the SignOut method, the session is not destroyed on the server side.

What is the impact?

If a session is not properly terminated and destroyed on the application server, then the session is vulnerable to session hijacking. This means that even though the user clicked on the logout button, an attacker may continue working inside the authenticated session.

Every authenticated session is identified by a unique session token. This session token is stored in a cookie in the browser. Because your browser submits this cookie to the server for every page that you request, the web application is able to identify you as a user and can give you access to all your data. However, if an attacker is able to obtain the value of this session token (through various methods which we don't discuss here) then the attacker also has access to your data in the application. 

One would expect that when a user clicks on the logout button that the session token loses its value. This is however not true in ASP.NET's forms authentication session management scheme. Even after logging out, the session token remains valid and the session keep on living on the server side until it times out.

What happens in practice?

When using the FormsAuthentication.SignOut method the web application clears the cookie in your browser. So for all subsequent requests, the unique session token is no longer sent to the web server and so the server no longer associates you with the authenticated session. If for some reason you start sending this cookie again, the server will associate you again with the session.

The browser flow below shows the different cookies that are being set and reset by an ASP.NET web application using forms authentication.

  Browser request Web application response
Log in #1# GET Login.aspx Returns login form.
Set-Cookie: ASP_SessionID=abc
#2# POST Login.aspx
Cookie: ASP_SessionID=abc
Authenticates user, redirects to homepage. The browser receives the session cookie.
Set-Cookie: FormsAuthentication=xyz
#3# GET Homepage.aspx
Cookie: ASP_SessionID=abc; FormsAuthentication=xyz
Returns homepage.
Perform authenticated user action #4# GET MyAccount.aspx
Cookie: ASP_SessionID=abc; FormsAuthentication=xyz
Returns information about your account.
Logout #5# GET Logout.aspx
Cookie: ASP_SessionID=abc; FormsAuthentication=xyz
Logs the user out. The session cookie is reset in the browser.
Set-Cookie: FormsAuthentication=
Trying to request the MyAccount page again now fails. #6# GET MyAccount.aspx
Cookie: ASP_SessionID=abc; FormsAuthentication=
Access denied, since no valid FormsAuthentication cookie was sent.
Replaying the cookie will succeed. #7# GET MyAccount.aspx
Cookie: ASP_SessionID=abc; FormsAuthentication=xyz
Returns information about your account.

Why isn't this weakness fixed?

I'm not an ASP.NET developer so I cannot verify this, but some sources explained that a Forms Authentication session is not tracked at the server-side at all. The application server solely relies on the FormsAuthentication cookie to know who is visiting the web application.

This would however also mean that the FormsAuthentication cookie is not just a random value, but an encrypted string that contains a reference to the authenticated user's ID.

How to mitigate this weakness?

As a developer you have to keep track on whether or not the user is still logged in. It is recommended to set a certain "Logged_In" boolean value to True immediately after logging in and to store this boolean as a session variable on the server. When the user clicks on the logout button, then you set this boolean value to False.

If someone keeps on using the session token and the boolean is set to False, then you know that someone is replaying the token and you can redirect all requests to an Access Denies page.

Cookie replay references

The weakness and exploitation of it is definitely not new. It has been described in many web application testing references:


You might also be interested in...