Int-UserID and Session in ASP.Net unsafe? - asp.net

I am developing my login for my new homepage.
Now I found out, that I must save something like the userID (or another value that i can recognize my user) in the session variable of the browser.
At the moment I use INT for the userID.
So isn't it unsafe to put the userID in the session?
E.g. when I edit my session variable manual from userID 111 to userID 112, than I am logged in as a complete other user?!

Yes, it is unsafe to rely only on user ID.
You may wish to add a unique authentication token generated and remembered by the server. Also a very simple solution, but it will stop manipulating the user ID since the correct value for authentication token for the other user cannot be guessed.
You also need to submit both user ID and the corresponding authentication token at each request to be jointly validated on the server side, prior to performing the requested operation.
P.S. The above applies if you store this information in cookies which are accessible on the client side and can be manipulated. The viewstate (serialized in pages) can also be manipulated. The session collection is a server-side variable that is not available on the client so it cannot be manipulated. In this later case your user ID should be safe.
I would recommend you to implement the dual system: store the user ID and the token both in cookies and in the session and use the same validation logic (for simplicity). Should cookies be disabled you automatically fallback to using the session without changing your code.

The session variable is not stored in the browser, it is stored on the web server. (Typically anyway.)
A token indicating which session variable to use, is stored in the browser.
So storing the userid in the session variable is fine, as the user has no access to this directly.
If the user were to change the session token, to another one, that would be a problem, but they'd need to know the other token first. (I'm not sure how to do that myself.).
(You can further diminish this by using encryption, or other identifies like IPAddresses etc, it's really a case of how secure do you need your website to be?).
Also, if your site needs the user to log in, it's advisable to use https/SSL.

As Bravax says, the user does not have access to the Session variables (Cookies they do have access to).
If you are worried at all I would use a GUID instead as they are not sequential and nearly impossible to guess.
Also, have you looked at the built in stuff in .Net for authentication? Look at FormsAuthentication.
HTH,
Arry

Related

asp.net core identity claims vs properties (efficiency point of view)

i've read all the tutorials and questions asked about the subject but they contradict one another
claims(userclaims and roleclaims) are serialised into a cookie (along with custom identity user properties you specify by overriding the principle factory) but they don't get queried, they're stored in a cookie, which mean that the more claims a user have, the more data will have to round trip between the server and browser
a custom identity user property by default don't get serialised but get queried from the database, so every time you need that data it query it from the database which is more work to do on the database on each request if you frequently query for it
so which is more efficient and which is safer
for instance
IsAdmin should be a role/claim? but then if someone stole the cookie, nah nah, the cookie already contains userid/username/securitystamp, so even if it's a property, the userid on the stolen cookie would query on the custom identity user property, or is there something that will prevent this cookie from working when stolen ?
another instance
if i've 20 property for the user (first name, last name, address 1, address 2, postal code, whatever the case may be), should i simply have the user wait a bit for a bigger slower cookie to be send back and forth or should i do all the work from the db using custom identity user
but then, if i remove or add a claim to the user, would it be updated on the next request if it doesn't get queried or is the security stamp validate that this cookie is still valid ?
cause at the Task AddClaimsAsync of the userstore of efcore it only add the claim to the dbset
i apologize i know this is many questions to ask but the resources on the matter are not that good and one can easily get lost reading the identity source
Rule of thumb - put frequently added items as a claim, everything else can live in DB and be queried on demand. I.e. address 1, address 2 can't be required on every request, so keep them in the DB.
On the other hand IsAdmin (should be a role anyway) I can imagine will be checked on every request, so it should be in the cookie without having to query the db.
If you afraid of your cookies getting stolen, don't show them to anyone! set up SecurityStampValidator to do frequent checks - like every 5 minutes. This basically updates the cookie with the fresh information from your database and changes the cookie. So even if the cookie is stolen, it will only work for 5 minutes.
I don't think the two statements contradict, it depends on your configuration. The second statement mentions "by default".
You do not need to store all information in claims nor do you need all the information all the time. If you want profile information, call the server once and store the information on the client, or get it when needed only.
The same counts for authorization, in case you want to show / hide elements based on permissions. This may include a tag called "IsAdmin". Authorization should be kept close to the resource.
If your client wants to refresh the information, just call the server. Claims are not updated during each request. In general, the user has to log out and log in again. So Claims are not flexible and therefor not really suitable for properties that can change (frequently).
As for safety, it doesn't really matter that the client can alter the information, it is for display only. It doesn't change the permission in the backend.
You can consider to add something like a display name to the properties, if you are showing that in every page. You can also consider to implement caching to limit database calls. In the end it really depends on your requirements.
As for stolen cookie, you'll need to implement additional security to your server to detect suspicious behaviour. You may want to include the ip address as claim. As for the admin, add security, e.g. filter by ip address and / or use an additional code which was send by email.

Not handling authentication, but need claims and cookie

I am creating a new asp.net MVC 5 application. Authentication is handled by a third party using smart cards. Once a user is authenticated by the third party, I am sent the user's unique ID (inside the http header) which I match up against my database in order to find relevant information about said user (roles, display name, etc.).
Currently, on every page request, the sent user ID is compared against the database, and checks are performed to ensure the user has the proper permissions to view the requested page. While this works, it sure seems like a bunch of needless database hits when all the user information could just be stored in a cookie.
If I was using Individual User Accounts for authentication, what I am looking to do would simply be built in using Identity and OWIN. But since I am not handling the authentication, but merely the authorization, is there a way to use all the nice features of Identity and OWIN (claims and cookies specifically)? If not, how might one go about this?
Also, of particular interest to me is when a role is added or removed. Using OWIN with Individual User Accounts, updating the cookie is as simple as logging the user out, and then back in immediately in the background. That functionality would also be desired for any solution presented.
Any insight would be extremely helpful. Thanks for reading!
You could do what you're asking by directly storing values in a custom cookie, but for your purposes it sounds to me like you might be more interested in utilizing sessions to track that info. This will keep all of your actual data stored server-side, which is more secure as it isn't vulnerable to cookie modification and it allows you more freedom to control the state (for your role example, you wouldn't have to "update" the cookie at all, just update the session variable on the server side to add or remove the role as needed).
Figured it out. Found a great article that really helped:
http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux

Store tenant id in the asp.net session?

I am building a multi tenant MVC4 web application. I distinguish the tenant based on the url alias (customername.webapp.net). I have a database that stores the customer id which I can lookup using the customername.
Obviously I need this customer identification during the entire session that a user from that customer is using my webapp.
Is it acceptable to store this unique identifier in the session? Or are there better design choices for this kind of "session data"?
I'd rather store this information inside the UserData portion of the forms authentication cookie (if you are using Forms Authenticatoin) or simply add it as a claim if you are using claims based authentication. When the user logs-in you would extract the tenant name from the current request, query your database in order to obtain the tenant id and then persist this id. If you store the id in the UserData portion of the Forms Authentication cookie you could write a custom [Authorize] attribute which will read the FormsAuthenticationTicket, decrypt it, get the tenant id from the UserData portion and then build a custom principal. This way you will have it available everywhere in your application. If you use claims based authentication, you would simply add it as a new claim.
I wouldn't use Session at all inside my application.
Please don't be misguided by the answer. It is dangerous to use cookie.
Session in this case would be the valid option, not cookies. If you store your tenantId inside your cookie, and your application establishes database connection based on your cookie, then after you login as a user, you can tamper and change the cookie and now your application will make connection to another database thereby compromising security. Even if your cookie is encrypted, it's not 100% reliable.
Session in this case would be the reliable server information that keeps track of which tenant database should be connected to. Although session can be a performance drop compared to cookie, in this case you have no other good options. You are designing a multitenancy application and that's just something you have to sacrifice.
Yes, you may still able to use cookie if you REALLY want to. You just have to keep checking if the user is connected to the right database somehow, which to me is more of a performance drop than using session.
Don't hate session just because alot of people abuse it or hate it. You just have to use it in the right manner.
Bottom line is, if you are using any info for security purposes, don't use cookie.

Invalidate session of other user

I've made an asp.net site, which uses Session objects to store information for each logged in user. To check if a user is still logged in, I check if a certain object exists in the Session.
The system used Jasig CAS authentication, and the single sign on part works (as in: after the log in, the Session object of the user is set up correctly).
CAS also supports single sign out. The way this happens is that CAS calls a url on my site, with some parameters about the CAS session.
What I need to do now, is invalidate all Session objects for the specified user.
How can I, from a page on my site, invalid the Session object of a random other user? Is there a db I can clear, is it all in memory (I can look at web.config if I know what to look for)?
I've seen this question asked before, and most answers are "keep a global variable next to the Session global variable, and check that one too to see if the user should be logged out or not", but I don't like that solution...
Cheers!
The session is by design private to individual users. Therefore to abandon it, it has to be done by the user.
So you might have to use another a list & check that.
Ideally though, you shouldn't tie your authentication state to the session. Whether the user is authenticated or not should be independent. You can then choose to abandon the session by querying the authentication state. It also makes it easier to implement mechanisms like counting logged in users & ensuring login from only 1 location - should you require these.

Authorization security of ASP.NET Forms authentication

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?
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.
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.
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:
User logs in.
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.
Use this token and save it in the cookie instead of usernames or other info.
If user logs-out, clear logon security token from the data store
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.

Resources