FormsAuthentication: Is it secure?

Peter Bridger picture Peter Bridger · Feb 8, 2011 · Viewed 10.7k times · Source

Using FormsAuthentication build into asp.net it's very quick and easy to create a login system that creates a cookie for authenticated users:

FormsAuthentication.SetAuthCookie(uniqueUsername, false);

Paired with some code in the Web.Config file:

<authentication mode="Forms">
  <forms loginUrl="Login.aspx" timeout="30" defaultUrl="Dashboard.aspx" protection="All" />
</authentication>
<authorization>
  <deny users="?" />
</authorization>

This will bounce all requests back to Login.aspx until the user is approved and a cookie is created using the SetAuthCookie() method call.

Is this secure enough?
The rule of thumb I use is that I don't store any data on the client that they've not sent me. So what I've done in the past is hold the username and password used in a cookie, then re-authentic this with every request.

There's the extra overhead of re-authenticating everytime with this approach, but it also means I've not storing any server data on the client.

My worry
My concern is that by using the SetAuthCookie() method call, that the username is being stored on the client machine. Is it then possible for someone to break the encryption being used and substitute the username being stored for another?

I think I'm being overly paranoid and that the type and level of encryption being used is adequate, but thought I'd get some expert input on the topic.

Answer

Scott Mitchell picture Scott Mitchell · Feb 8, 2011

So what I've done in the past is hold the username and password used in a cookie, then re-authentic this with every request.

You should not use this approach. The password should not be stored in an authentication ticket. The reason being is if the authentication ticket is compromised then the attacker has the user's password. This risk can be mitigated by encrypting the authentication ticket cookie, but I presume you were storing the cookie in plain-text.

My concern is that by using the SetAuthCookie() method call, that the username is being stored on the client machine. Is it then possible for someone to break the encryption being used and substitute the username being stored for another?

As Shiraz noted, the cookie is only persisted on the client machine if you create a persistent cookie. (One of the parameters to SetAuthCookie indicates whether or not to create such a cookie.

Even if someone broke the encryption scheme to modify the cookie to supply a different username they'd run into problems because the authentication ticket is also digitally signed, meaning ASP.NET can detect if the contents of the cookie have been modified. To forge a digital signature the attacker would need to know the salt used by the server, and if the user can figure that out it implies he has access to your web server's file system, so now you've got bigger problems.

Another thing to understand is that the authentication ticket has an expiry, which puts a finite lifetime on the validity of the ticket. So even if someone were to steal a user's cookies, the time the attacker would have to use that stolen ticket would be limited based on the timeout value you specify for the forms authentication system (30 minutes by default).

In conclusion, the official ASP.NET forms authentication system is going to be much more secure than something a lone developer will be able to implement. Developers should strive to use the forms authentication system rather than roll their own solution for a myriad of reasons, including better security, not having to reinvent the wheel, adopting standard practices so other developers who join the team don't have as large a learning curve to get up to speed, and so on.

For more nitty gritty details on the forms authentication system and how the ticket is secured, how the various <forms> configuration settings work, and so on, see: Forms Authentication Configuration and Advanced Topics.