What are the pros and cons of using session variables to manage a users session data? - asp.net

Using ASP.NET I have always used session variables to maintain a users session data.
Typically: (Coded as simple bools/ints with around 12 total variables)
User information.
Page security permissions.
I have read increasing information regarding the negative effects of using session variables.
I am aware that session variables are stored in memory and the negative effects that using too many can have; this is not the desired scope of this question.
What I would like to know:
Using current development languages and features:
Do session variables pose a security risk?
(By security risk I mean is it possible to read / alter variables)
Is there better performance using querystrings, viewstate, caching, or making database request on every page load?
What is "considered" good practice for handling a users session data. (All topics relating to this subject are now very old and perhaps no longer relevant)?

A performance is always something subjective and may vary depending on different things. In your case you're trying to compare incomparable because
querystrings cannot be used to share sensitive user information or page security, because everyone can modify urls directly in the browser
viewstate is set and maintained on the page level. It cannot be carried across different page requests, only on postbacks of the current page.
caching is done on the application level, and all users can access it. It might work in case of page security permissions but not applicable to store individual user information.
Making database requests is the only comparable option and yes, it's slower than a session. This is where you can try to play with viewstate and caching and try improve performance and reduce a database workload.
Sessions are stored in a memory on the server but depend on cookies and in theory, it's possible to hijack the session by stealing the asp.net session cookie.
SessionID values are sent in clear text. A malicious user could get
access to the session of another user by obtaining the SessionID value
and including it in requests to the server. If you are storing
sensitive information in session state, it is recommended that you use
SSL to encrypt any communication between the browser and server that
includes the SessionID value.
Quote: http://msdn.microsoft.com/en-us/library/ms178581.aspx
Bottom line: using sessions is secure but to make it more secure use HTTPS
ASP.NET provides out of the box functionality for user authentication, role based authorization and user profiles which might make sense to use. Read more about profiles: How to use Profile in ASP.NET? and Regarding Profile and session in asp.net There is a lot of other topics and answers here on this site regarding authentication and authorization.

Do session variables pose a security risk? (By security risk I mean is it possible to read / alter variables)
Although, as smirnov quoted, a malicious user might get accrss to another user's session by hijacking the session itself, the session variables themselves are stored at server-side, and cannot be accessed directly.
Is there better performance using querystrings, viewstate, caching, or
making database request on every page load?
As smirnov wrote, the comparison isn't exactly valid. However, consider:
querystrings and viewstate are stored in the http request, therefore are both less secure and consume no memory. However, they will take some minor processing power to parse.
Caching (in the web-server RAM) the results of previous database request will lighten the load on the database and the network connections between your web-server and the DB server, and will also retrieve the data faster. However, they will obviously use more RAM on the web-server itself.
What is "considered" good practice for handling a users session data.
(All topics relating to this subject are now very old and perhaps no
longer relevant)?
Since the principles haven't changed much, the existing sources, IMHO should still be relevant.
Note: If you're using multiple servers, you'll need to synchronize the session data across them, by using a state-server, for example, or use "sticky sessions", in which each session is always served by the same server.

In my opinion you should avoid sessions as much as possible. Here are my reasons in no particular order.
Sessions doesn't scale automatically when you add more nodes (Sure you can use a dedicated session-server but that comes with some overhead)
When you have enabled sessions each user can only make a single request at the same time. Asp.net implements per user locking if the session is enabled to avoid any race conditions. This is mostly a problem in if you use a lot of ajax.
If you have to restart the webserver the user lose their session. This is really the main point for me. It really sucks to have a system where people risk to get kicked out, get a corrupted session or simply lose progress because you need to deploy a bugfix. Avoiding session as much as possible gives you much more freedom and a better experience for your user.
It's up to you but I always try to either store the data in a persistent store or use something that actually exist in the web (cookies, querystring, writing state to a hidden field etc etc). I bet there are situations where I would use sessions but my default choice is to avoid them.

These days there are more options:
Local Storage / Session Storage / Page Javascript Variable - are good for client-side storage situations. see https://www.w3schools.com/html/html5_webstorage.asp. But they wouldn't be suitable for most trust situations, not without server-side signing. A javascript variable will be lost upon page restart, but persist in browser Session Storage if it was written there. If that browser tab is closed, the Session Storage is lost, but persist in the Local Storage if it was written there.
JSON Web Tokens (JWT) - are the emerging new standard for replacing Sessions. This is a standard for authentication, roles, data, and claims, which is signed by the server, and can also be encrypted to the client can't read any of the details. This is usually stored in Local Storage by the client, and only really works for Single Page Applications which can write to the Bearer header. Don't use this for MVC (MVC.Controller) with server-side generation of HTML. JWTs can be a pain to set up and customise - the API for OWIN is terribly sparse. JWTs can get big too, which means you're always "uploading" the JWT data upon each Request to the web-server. But JWTs enable your security to be handled by one server (even an externally trusted server).
ASP.Net Server-Side Sessions - Can be in-memory in-proc, in-memory external-proc, and database.
Answering your specific questions:
Security risk - Not really. The session uses a key that's long enough that it can't be guessed. It's typical to use HTTPS these days, so that value is securely transmitted. The variables are stored only on the server, with a set per user. If a user's device is compromised, it's possible to steal the session key, but if their device is compromised, there are bigger problems to deal with.
Performance is not better or worse for "query strings", "view state", or "caching" compared to In-Proc (Memory) sessions. They're all in the realms of speed of memory (RAM) - nanoseconds. Database (disk stored) is certainly slower, because the medium access time is slower - milliseconds
Sessions are good practice. Some would recommend having a dedicated class for reading and storing each variable (using Properties), so you don't get the session variable names (strings) confused.
I am a fan of a possible hybrid approach to Sessions. see How can I store Session information in a hybrid (Database + Memory) way?

Related

Seurity ramifications of ASP Session

I'm looking into storing some security sensitive information (a users effective permissions for our web application) in a session-resident object, to reduce database queries while performing permissions checks throughout the app.
I understand that the session is stored server-side, and not directly accessible to the client under normal circumstances. ASP.net's other persistence mechanisms can be theoretically defeated, by modifying viewstate or cookie values client-side, but these kinds of cryptography implementation flaws should not expose session-state.
What degree of control over your server would an attacker need to modify data in a clients session-state? Assume they have a sessionID, and an ASPAUTH cookie.
For instance:
A remote attack, like a modified POST or other handler call to a
page?
Would an attacker with programmatic access to IIS (WMI mabey?)
be able to access and change session-state in the same or another app pool's memory?
Would an attacker need to be able to post code to my app, in order to manipulate session memory?
I know these kinds of questions often rely on mistakes in my code, so by all means assume I've written the worst, most insecure code ever (I haven't, but...) and do things like change session in a constructor or life cycle event.
Since we don't know exactly how your code is implemented, all we can do is guess.
First, Session should NEVER be used for security sensitive things. Yes, it's true that a client can't directly read session, there are other factors to consider.
Session cookies are not, by default, encrypted and are passed as plain text.
Session Fixation attacks are easy to accomplish
If a session cookie is hijacked, or even guessed, then it doesn't matter what the users account is, they will get whatever security rights you assign via that cookie.
Session is unstable, and IIS can kill sessions whenever it feels like, so you end up with the situation where a user is still logged in, but their session is lost due to many possible reasons. So now their security is also unstable.
There are many other, more appropriate ways to do what you want, Session is NEVER an appropriate method.
Other methods that would be appropriate include...
Using the user data field of a FormsAuthentication ticket to store the information
Using a custom Claim with a claims based authentication, like ASP.NET Identity, WIF, or IdentityServer.
Using the asp.net Cache to hold the temporary information, based on identity (not session) and adding a cache eviction timeout.
and many more...
Session variable can be a security risk. It is always better to secure your session variable.
Few links you should take into consideration...
Securing Session State
http://msdn.microsoft.com/en-us/library/ms178201%28v=vs.140%29.aspx
http://www.dotnetnoob.com/2013/07/ramping-up-aspnet-session-security.html
http://www.codeproject.com/Articles/210993/Session-Fixation-vulnerability-in-ASP-NET
http://www.dotnetfunda.com/articles/show/730/session-security-in-aspnet
I agree with Erik views.
regards

which will give better performance while creating a website a session,cache,or cookie?

I am creating a website,for that I need some kind of storage medium so which one can I use and which one will give better performance to the website.
session
cache
cookie
please give your suggestions.
It all depends on the scenario and their usage.
Basically Caching is used to boost performance and Session is used to share data between multiple pages. Excess use of session bogs down the performance. Cookies are stored on client side and can be used to keep less confidential data on Client browser.
So you have to use all of them wisely to deliver performance
Session is used to store per-user information for the current Web session on the server.
Cookie is used to store per-user information for the current Web session or persistent information on the client, so client has control over the contents of a cookie.
Cache is shared between users in a single application. Its primary purpose is to cache data from a data store and should not be used as a primary storage. It supports automatic invalidation features.
If your application is used by a number of unauthenticated users, then it would be better to store the data in a cookie.If it requires authentication, you can store the data in the DB manually.
On whole this it depends on your need.
session is a way to store variables stored in a session object so that it is accessible to all web pages hosted on the server for a user.
Cookies stored on client machine so not much safe to go for it unless variable are not so restricted.
Cache helps your browser go faster.Hence Caching is used to build high performance web applications.

Is a Session-Less Design feasible?

Just brainstorming some ideas for a Web App I'm building soon.
One of the cornerstones of the Web is Session Handling: Have the user log in, send a cookie with magic binary encoded pixie dust, trust the user blindly afterwards.
I just wonder if it's feasible to completely eliminate 'traditional' sessions for a web app that would normally use it, e.g. an online store.
The idea would be to have a 'server side session' that doesn't use the SessionID or anything, but the username instead. So there is exactly 1 session per user, not more. That would allow stuff like a persistent shopping cart to work.
Authentication would be handled similar to how Web Services work: Expect HTTP Digest authentication on every single page view.
Ignoring the fact that anonymous visitors would have to be handled differently, do you think this approach would be feasible? Or would the additional traffic/load for constant authentication be a deal-breaker in the long run?
First off, we don't use sessions at all.
We found that utilizing session complicated the code without any benefit. There are only two reasons to even consider using session state. The first is to reduce the amount of traffic to your sql server.. However, with load balanced web servers etc, session has to be stored in a sql server... Which kind of eliminates it's first point. But it's worse than that as the session has to be retrieved, deserialized, serialized, and stored on every single page load.
The second reason is to keep from having the browser pass the user id back to the application on each request. However, "session hijacking" is a fairly easy trick to pull off and is rarely taken into account.
So, instead, we use a highly encrypted cookie with non-guessable values that indicate exactly who the user is. We've coupled this with a changing, non-guessable, request id and have eliminated both session state (and it's unnecessary overhead) while at the same time improving security all around.
Can the cookie be stolen? Sure, but it has a very limited life that is the amount of time between two postbacks. Which means it will be found to have been compromised rather quickly.
So, I wouldn't say sessions are a "corner stone" of the web. Rather I'd say they are crutches that are often used improperly and should be avoided for both security and performance reasons.
All of that said, the only way you are going to tie this to a user id is if you force your users to login/create account prior to shopping.. Which no one is going to do unless they have no other choice but to be on your site.
Oh, and don't take my word for it:
4GuysFromRolla.com -> Session variables are evil.
aps.net -> Are session variables still evil?
Scott Hansleman -> Moving Viewstate to Session Pay attention to the part in bold covering memory consumption and it's ability to stay around for way too long.
Coding Horror -> Your Session has timed out This details just some of the problems associated with even using session
Wikipedia -> Session Hijacking What list would be complete without a link to wikipedia?
REST-like implementations such ASP.NET MVC do not require session state at all.
You should just use sessions. Even if its your own session implementation: eg. cookie contains random key used to store information the server. A cookie must be used or you will have to encode all links on the site with a query parameter that specifies the key -- bad idea!
I would then store the "session key", or what every you want to call it, with the persons username in the database.
When a user logs in to your site simply restore their previous "session".
Other then the query parameter option, which is a bad idea, you can track users by IP address. But this again is a horrible idea! Eg. many buildings have a limited number of Internet IPs and many times more internal computers.
There is no good way to track a user without using cookies.
Yes maybe you can use HTTP authentication but why bother? You are just going to introduce new issues and put limitations on your UI.
That actually is pretty much what a traditional session does -- provide a unique identifier to distinguish a browser "session", all you are doing is tying it to username rather then a random variable.
I would say just be very careful of how you generate your token, if it is reproducible you could easily accomplishes the goal of a session fixation attack by generating someone elses session and jamming it into a cookie. That is the reason that sessions are usually a random unique value.
The idea would be to have a 'server side session' that doesn't use the SessionID or anything, but the username instead. So there is exactly 1 session per user, not more. That would allow stuff like a persistent shopping cart to work.
That's just a session, but using the username as the session identifier - which is going to cause all sorts of problems - its open to replay attacks even if you encrypt it. You can't change the encrpytion per-request because that will break when the user opens a second window or presses the back button.
You can't rely on the client address - multiple users may share a NAT address, the same user may access your site from behind a cluster of load-balanced proxies.
like a persistent shopping cart
...implies that you have server-side data for the customer - since the size of this data will vary, you can't store it in the URL nor in a cookie.
Expect HTTP Digest authentication on every single page view.
That presupposes that you create accounts for every user, and that you're not concerned about the impact of the same user id being used by different clients. I don't think that this would require significantly more processing than a conventional session - but its still web-based session management with a different set of problems and vulnerabilities compared to the conventional approach.

Role Caching Strategies in ASP.NET MVC

We have an ASP.NET MVC application for which we have developed our own custom RoleProvider class. Without caching it will access the datastore for every request - bad. The only caching option we can find is (in web.config) via cookies stored on the clients' machines. My two questions are:
Is this secure (even with encryption enabled)?
Will the cookie information be transmitted with every web request - thus, potentially, slowing the application more than accessing the datastore every time?
Does anyone have an alternative route? I understand that caching this information in the Session is also bad?
If you have developed your own custom RoleProvider class, you can do your own data caching, e.g. using the ASP.NET cache. This is more flexible than using Session as a cache, since it will work even on pages that don't have session state enabled.
I don't agree with Wyatt Barnett's comment that:
The downside for using the Session
... the fact that Session storage is
very violate and not particularly
reliable
It's OK for a cache (whether Session, the ASP.NET Cache or something else) to be volatile - you just need to repopulate it when required.
To answer your questions:
It's as secure as the encryption used to encrypt the cookie. If you're relying on FormsAuthentication, it need be no less secure than the Forms Authentication ticket.
The cookie will be transmitted with every request. So there is a potential performance hit if users can have a very large number of roles, and the potential to exceed the maximum cookie size supported by the browser.
While the idea that querying the DB each request is inefficient is true, but remember that SELECT performance on properly indexed tables in modern DBs is blazingly fast, so I would first take some measurements to be sure that this scenario actually negatively effects performance versus theoretically could negatively effect performance at a later date.
The downside for using the Session isn't so much the overhead (minimal) as the fact that Session storage is very violate and not particularly reliable. You can easily lose the session and still have a logged in user, for example.
That said, a good way to settle in the middle here would be to cache the user's roles per request using the HttpContext.Items collection. This will limit to one SELECT per request, which is probably reasonably efficient (cf measurement above) while avoiding the other storage issues--such as a fat, insecure cookie or some rather violate Session-based solution.
The cookie information will in fact be sent from the browser to your web server with every request, that's just how cookies work, but as long as the size of the cookie is reasonable it shouldn't have too much of an impact on performance. If you are using forms authentication I would recommend storing the roles in the forms authentication cookie as described in this blog post. In that case, you are just adding data to a cookie that already exists. You should be aware that there is an upper limit to the amount of data you can store in that cookie however, as described here.

what is the efficient way to store session variable

My asp.net application is deployed on a load balance system. And I just want to keep a user's role (a string) in a whole session. I was told that session info in asp.net is stored in the database so I don't want to the asp.net engine to access DB ecah time a user switch between pages. neither do I want to get the role from my own DB each time when I need check user's role. I know one way is to store the role info in a hiden field.
what is the efficient way to store a constant session value?
session has three modes. The mode setting supports three options: inproc, sqlserver, and stateserver. you need load balance, the inproc is out automatically. you can configure to use either sqlserver or stateserver.
If you want to avoid DB accesses, you might use cookies to store the user's role instead of session state. You can encrypt / encode the cookie if you need to for security reasons (perhaps using the session ID as part of the key). Cookies work fine in a load-balanced scenario, since they are sent by the browser to the server with every request. Just be sure to set the path attribute on the cookie (and possibly HttpOnly), to limit the URLs that the browser attaches it to.
Note that if you're using the built-in ASP.NET Membership providers, role membership and related details are handled for you automatically by the providers.
You could also use a cookie.
Session data is stored by default in memory, so i guess you have it configured to be stored in a database in order to be available on all servers in the farm.
If you can store it in memory, you could use this approach to deal with the load balancing:
if (Session["Role"] == null)
Session["Role"] = GetUserRole();
This will result in trips to the database only once per server.
More details about Session state here.
If "role" has something to do with permissions it would not be a good idea to store it in a hidden field or an other means that would enable it to be edited from the client side such as in viewstate with talking asp.net.
I am a big hater on session, especially if you are using it to hopefully improve performance. What you probably really want is caching and there a number of great solutions you can look into. Right away you can take advantage of the Cache data dictionary that is built into asp.net and is exposed as a member on the page class. The cache will essentially serialize anything you put in it and store it in memory. Using the cache object will work best with a single server setup. Since you are using load balanacing you will probably want to take advantage of a distribute cache system like Memcached or AppFabric Caching (Previously Codename Velocity). Memcahed is used by a lot of big sites such a Twitter where as AppFabric is a new Microsoft product that is just becoming available but should have good support and integration with other Microsoft technologies such as Asp.Net.
With distributed caching you avoid going back to the database and you essentially trade this off for a trip to your cache. The reason why this is more efficient for starters is that the cache only has to worry about efficiently storing items which have been recently accessed where as the database must store everything.
Also I want to point out that you may choose to avoid the distribute caching route if you are using server affinity with your load balancer. Technically you could use it without server affinity as well but you will have a lot more cache misses.

Resources