views:

142

answers:

3

I'm using Forms authentication in ASP.NET MVC website and I store user account login name in AuthCookie like this:

FormsAuthentication.SetAuthCookie(account.Login, false);

I want to ask if there is a possibility that user on client side will somehow manage to change his login name in AuthCookie and thus he will be for example impersonated as someone with higher privileges and authorized to do more actions than he is normally supposed to have. Also is it better to save in this cookie user account login name or user account ID number?

+4  A: 

The cookie will be encrypted and decrypted on the server side, so unless the user can crack the encryption key, he or she won't be able to do this.

As long as the information you store uniquely identifies your user, the choice as to what that information is is entirely down to the requirements of the particular application.

David M
what @David said
Andrew Bullock
+2  A: 

No it is not possible (well, in theory maybe but it's not feasible in practice). The value of the authentication cookie is encrypted so the user can not tamper with it. It is a good idea to store the (unique) login name in the authentication cookie, because when the IIdentity object (HttpContext.Current.User) is restored, the value that you passed to SetAuthCookie is used for the Name property of the IIdentity. The Name property will be shown if you use the LoginStatusControl, for example, so it's a good idea that the value of the Name property makes sense to the user.

klausbyskov
That's a good point, but in my scenario I have completely AJAX based application, login status is loaded only once during the first request and each AJAX request is loading module authorization privileges based on user account ID, so I will spare one extra inner join in my SQL query on each AJAX request when I use ID instead of name.
Tomi
+1  A: 

Cookies are encrypted so chances for that a quite slim. But still.

More than one property approach

If you'd like to make your security even tighter you could save username as well as user ID or some other data that can't be guessed from the username. The combination of these makes it safer because if you can guess one it harder to guess others and use the correct combination of them. Ie. If you guess other user's email/username it's a bit harder to guess the same user's ID, because they're not related. So the more unrelated properties you combine the more steps it takes to get the right combination.

Logon security token approach

You could use an alternative approach described in this scenario:

  1. User logs in.
  2. Generate a random security logon token that can be of random length with some minimum length defined and save it against user in the data store. This is probably not a problem while it's quite common that other data is stored at logons as well like LastLogonDate info.
  3. Use this token and save it in the cookie instead of usernames or other info.
  4. If user logs-out, clear logon security token from the data store
  5. User logs in again... go back to 1 and create a new token again and use it in this session.

This way it will make it safer on the long run, because this information will change on each login and if user does manually logout you can always clear that token from the store, so it won't at all be possible to inject someone else's identity. This does make it a but more complicated to use permanent cookies though but it can still be done.

This approach is not bullet proof but it provides additional security level that prevents the same attack over and over again when one account has been compromised. And also when one account is compromised it doesn't mean that others can be as well. If your security tokens are long enough it would be much harder to start a brute force attack on your site and while this kind of attack would be executed security tokens will change so it is definitely safer.

Robert Koritnik
If you're worried about the cookie security being compromised, the last thing you want to do is follow the more than one property approach and include enough information to reauthenticate the user from scratch in there...
David M
@David M: As long as the info doesn't reveal any personal information (assuming username is not personal) you're fine to go. IDs/SIDs/GUIDs are a good companion. Especially if you use SIDs or GUIDs, because they're usually not consecutive numbers and longer than usual, so they are harder to guess or brute forced. You could as well include contact info IDs/SIDs/GUIDs and you still wouldn't disclose anything. All of these would have to be checked when some cookie would be sent to the server and server wouldn't have cached user data. I guess these kind of combinations are a good way of doing it.
Robert Koritnik