Forms Authentication: Remember Me? Its Hard Not Too!
ASP.Net Forms Authentication is a great way to authenticate users for the application. Microsoft has done a really good job at implementing this to make it simple and straightforward for developers. Forms Authentication allows for a user to enter their user name / password combination for an application and have that validated against a backend data source. There are some built in providers to help make this a pretty seamless and painless process for developers. The basic workflow for forms authentication is:
- User attempts to access a resource (details.aspx).
- Server requires the user to be authenticated and redirects the user to the login page (login.aspx).
- User enters user name and password and submits these to the server.
- Server Validates the credentials and if valid, creates an authentication cookie (most common) and sends it back to the user.
- With valid cookie, user no longer needs to enter a user name and password to access the site on each page request.
The key point here is that, after initial login, only the authentication cookie is needed to access the site. In most cases, this cookie is non-persistent, meaning it will get deleted after the session has ended or the browser is closed. In addition, the forms authentication cookie is httpOnly by default, which is meant to limit client side script from accessing it.
Remember Me?
ASP.Net Forms Authentication has a feature to allow the application to “Remember Me.†this is seen on many login screens under the password box. By default, the only thing this built in checkbox does is determine if the authentication cookie should be persistent or non-persistent. When the checkbox is checked, the cookie will be persistent and live on after the browser is closed until it expires according to its timeout property.
From a security standpoint, it is usually not recommended for an application to allow automatic login in this way. What if someone else uses your computer or maliciously takes it over. In either of these cases, all they have to do is navigate to the application and they will be logged back into the application as the original user with no requirement for a password. To add some salt to the wound, many sites that implement the “Remember Me†functionality set the timeout to days, months, or even years.
Unfortunately, there doesn’t appear to be any easy way to change the default functionality of the “Remember Me†feature. For example, it might be more convenient to have the application just remember the user’s user name, and just require them to enter their password. From a security perspective, there could be an argument made that this is also taboo, but it is certainly better than not requiring anything. In order to achieve this, it would require custom code basically set up to replace the default remember me checkbox, or override its functionality. It is too bad that the build in functionality doesn’t have a property on it to determine if it is remembering everything, or just the user name.
Its Hard Not Too!
Now that “Remember Me†has been covered, lets dig a little deeper into the Forms Authentication Cookie (token). There is something important to know about a forms authentication token, the actual value stored in the cookie. The token has a built in timeout, and IT IS VALID until that timeout is reached. There is really no good way to kill a forms authentication token before its timeout period. Upon logout, you can call FormsAuthentication.Signout(), but the only thing this method does is remove the cookie from the browser. You may ask what the problem is if the cookie has been removed. The issue occurs if someone has been able to get that token before it was removed. It is beyond the scope of this post to discuss the ways that this could be done, but it can be done.
If someone access the token, they have free reign to use it, as long as the internal timeout has not expired. This is exactly why it is important to set a low timeout value. If the timeout is low, there is a smaller window if a user to use that token to attempt to keep it alive. With a large timeout, if an attacker got their hands on that token, they are good to login for the life of that token, or until you change your machine keys which may invalidate that token. This is a serious limitation of the token that developers need to be aware of.
There are many different ways that developers implement their authentication and authorization. Although this token can live longer than expected, at the least, it may just say you are authenticated. At the most, it could allow full compromise of the user’s account. For example, if the application additionally uses session state to validate if a user is valid then this would not be an issue because just randomly using the token on a new session would fail. There are many ways to handle this issue, the point is that we all need to be aware of how this token works so we can be prepare for the downsides.