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.
不过为了处理session hijacking的问题,在用户sign out的时候,会重置session。这样的话,没法保存数据。
可以考虑把数据存在HttpContext.Current.Application,只要进程没有被recycle,都是有效的。如果想要避免进程被回收的话,还是需要使用持久化的方案
情况1,
用户登录,窃取到ticket1,用户登出。用户再次登录,生成ticket2。此时用ticket1可以直接访问。
情况2,
用户在机器A登录,也在机器B登录。用户在机器A登出,会导致机器B上的用户被登出。
Cookie replay references
The weakness and exploitation of it is definitely not new. It has been described in many web application testing references:
- OWASP testing guide
- Version 2 (released in 2007) under section "4.4.6 Logout and browser cache management testing"
- Version 3 (released in 2008) under section "4.4.7 Testing for logout and browser cache management (OWASP-AT-007)" - See https://www.owasp.org/index.php/Testing_for_Logout_and_Browser_Cache_Management_(OWASP-AT-007)
- Version 4 (to be released in 2014) under section "4.7.6 Testing for logout functionality (OTG-SESS-006)" - See https://www.owasp.org/index.php/Testing_for_logout_functionality_(OTG-SESS-006)
- The Web Application Hacker's Handbook: the second edition (released in 2011) addresses this weakness in the section "Vulnerable Session Termination" under "Chapter 7 - Attacking Session Management".
- WASC classified this threat as "Insufficient Session Expiration" with reference ID WASC-47 - See http://projects.webappsec.org/w/page/13246944/Insufficient%20Session%20Expiration