views:

853

answers:

3

My website uses ASP.NET's forms authentication and i am inserting user specific information into the UserData portion of the authentication ticket/cookie. Since the UserData is inside the authentication ticket it is encrypted like so

authCookie.Value = FormsAuthentication.Encrypt(newTicket);

Now I am not too worried about the data being compromised at this point since it's encrypted. but i noticed that the data is available in unencrypted form like this

FormsIdentity fid = User.Identity as FormsIdentity;
string plainTextUserData = fid.Ticket.UserData;

The data itself is not too important. i am still ok even if other people can see it. but i cannot allow people to hijack this information and start using it as their own. for example, i don't want one user to be logged in pretending to be a different user (based on the userID contained in UserData

Is this something I have to worry about?

Edit 1:

The reason i want to do this is so i can stop using sessions and just use cookies and Ticket.UserData

Edit 2:

The data in Ticket.UserData is not changing. it's constant once the user is logged in.

A: 

You probably don't need to worry.

If the data is sensitive (for example, Social Security Number in the United States), then you should probably avoid sending it with the FormsAuth ticket, even though it is encrypted, because evil-doers are always conjuring up new attacks.

However, I have to ask: you already get to store an identifier with each ticket (username), so why wouldn't you keep all other data in the database?

Portman
i need more data on certain pages depending on what the user does. right now i am using sessions but now i want to move everything over into cookies. it's not a lot of data so i figured i could piggyback everything into the auth ticket/cookie
jorsh1
A: 

It is as secure as the authentication ticket. Since you are using it for the very same purpose, don't worry about it.

eglasius
+3  A: 

i need more data on certain pages depending on what the user does. right now i am using sessions but now i want to move everything over into cookies. it's not a lot of data so i figured i could piggyback everything into the auth ticket/cookie

@jorsh1 based on your commend to @Portman, Ticket.UserData isn't the place to store changing data. You don't want to recreate the authentication ticket all the time when going from one page to another.

Either use Session data with the Session Service or Sql Server. If you don't want the data in session, and the data is small and not sensitive then use a cookie. (*)

The MS canonical example with UserData is to store things like a list of Roles so that you can say things like "Do I think this user is an admin" but if it's something like an admin role, you'd probably hit the database to check before you implicitly trust what's in the cookie.

string plainTextUserData = fid.Ticket.UserData;

This does work inside your app only because Asp.Net has already decrypted the ticket for you. However, if you want to set the data IIRC you need to recreate and reattach the forms authentication cookie.

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
    currentTicket.Version + 1,
    currentUser.UserName,
    now,
    now.Add(formsAuthentication.Timeout),
    false,
    "new user data string",
    FormsAuthentication.FormsCookiePath);

string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
    FormsAuthentication.FormsCookieName,
    hash);

Response.Cookies.Add(cookie);

Another App can't decode this ticket unless it knows the decryption key or it was brute-forced. If you load-balance the App or use web gardens, you even need to keep the keys in sync.

* I'm not a proponent of storing things in session. Usually there's another way to persist that data.


[edit] What I use session for:

The only thing I often find myself doing is storing a lite version of the users critical data in the session-server based session. We however make it transparently-loaded, and make sure not to duplicate what's in the Ticket.

That way we don't expose anything sensitive in cookies, and we don't rely on session. We also set aggressive session reclamation. Combined with the small amount of data being stored in session, sessions don't cause us problems, and as only 1 piece of code knows whats in the session, we could refactor it easily.

For anything else, sessions are evil. I prefer to maintain viewstate within a page that needs it, or otherwise just persist the temporary state in the database.

Robert Paulson
thanks for the comments Robert. just so you know, the data in UserData is not changing once the user logs in. it's things like email, internal userID, username, etc. i'm wondering tho, what do you personally use instead of sessions? i'm starting to hate sessions myself.
jorsh1
right .. i updated my answer based on what I personally do.
Robert Paulson