Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how secure is the Ticket.UserData in User.Identity in asp.net

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.

like image 233
jorsh1 Avatar asked Mar 01 '23 23:03

jorsh1


1 Answers

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.

like image 107
Robert Paulson Avatar answered Apr 02 '23 21:04

Robert Paulson