I have a system that enables my Intranet users to process database records. Basically records are ticked/unticked and this updates a running total for each that is placed into separate session variables and then submitted to a different database. Every so often something odd happens and the values in these session variables can double (or worse) and I've never been able to replicate this (it does seem completely random and luckily rare).
I'm thinking about a possible rewrite and am wondering if it is better to go down the road of using cookies to store values temporarily, and then to force them to expire to clear these values.
As an alternative to these, is ViewState applicable here? I've read about it briefly but have no experience in explicitly setting viewstate values.
My main concern is that my variables were being affected by someone else using the system at the same time but I thought that part of the point of session variables was that they are only accessible by the session in which they were created?
ViewState is only used to post back data, it is not a replacement for either because it is not persistent across an entire session. It is a "view" state after all :).
Session variables actually use cookies, but in a more secure manner than simply by storing all pertinent data within them. Just storing values directly in cookies is fine, but users with a bit of simple JavaScript can modify the contents of their cookies. If you're not okay with that, then use sessions.
A small disadvantage of sessions in comparison to storing raw data in cookies is that the data is stored on the server, which does take up space and computing resources. Not much, but it is something to think about if you are going to have a high-traffic site or are thinking about storing everything and the kitchen sink in session.
So how do sessions work? They store data specific to each session user, accessible by a key. That key is usually stored on a cookie on the client's machine. When they access a page, their cookie key is transmitted to the server and relevant data is made accessible. One big thing to remember is that the security of the cookie is the linchpin of the security of the session. If you have a site which is vulnerable to XSS attacks (a subject for a whole other post), a user can steal the cookie of another and masquerade as them, because they will have the id that identifies the other user's session.
So overall, hard to tell you what system to use. Personally I tend to use sessions because they are easy to implement and the added security of not having user-modifiable data is nice. In the end though, you'll have to look at your architecture and decide what is best for you.
Related
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?
I want to implement measures to prevent/mitigate session hijacking. Thus, I want to know the options, either from built-in ASP.NET or custom components.
Please note that session hijacking refers to Forms Auth session and Session State.
My ASP.NET is using HTTPS for all pages all the time. But it is possible that session can be compromised once the session cookie id is obtained by third party somehow, e.g. from user's hard drive, cross-site scripting attacks, and man-in-the-middle attacks
In particular, I am concerned about session id hijacking because https is used all the time for my projects
Below is the links I reviewed, which are written a few years back:
Foiling Session Hijacking Attempts Jeff Prosise Please refer to Caveats section for its shortcomings.
I cannot find much relevant information, or different from Jeff's on the web.
Here are a couple suggestions:
Salt your sessionId. This would ensure that you have unique session Ids - although, I am pretty sure the default ASP.NET session Ids are unique enough for your purposes; however, for added security you could use something that either you can control or is self-identifying. For instance, you could use a GUID as a salt - which you can control by updating as you see fit.
Track the SessionId and user ip address of your users as a pair in a dictionary object. This would enable you to match the session Ids to the ip address and reveal any session hijacking that is occurring outside of the user's LAN. Obviously not without flaws as it won't matter much if the user's computer or router is infected, but it will at least make it more difficult for the attacker to accomplish their task.
Not sure what you would do if the user's computer is infected, but that risk exists whether you increase your defensive measures or not.
I've started ASP a few months ago, having come from a few years of PHP.
In PHP, I used a combination of cookies PHP sessions, cookies and storing the Session ID in the database.
When a person logs in, the Session Id is written to the cookie and saved in a column in the database. If the person logs off, the cookie is deleted, if the person forgets, that's okay since the cookie only lives for 72 hours.
Upon visiting the site, I check for a cookie. If it exists, I see if the Session ID exists in the database. If so, we have a match and the person can continue their session. If no match the cookie is deleted, as it was probably forgery.
If no cookie, the person must login. An old value for Session ID stored in the database is simply updated.
Now, with ASP, it seems there are more options. From this article: http://msdn.microsoft.com/en-us/library/ms178581.aspx
* Application state, which stores variables that can be accessed by all users of an ASP.NET application.
* Profile properties, which persists user values in a data store without expiring them.
* ASP.NET caching, which stores values in memory that is available to all ASP.NET applications.
* View state, which persists values in a page.
* Cookies.
* The query string and fields on an HTML form that are available from an HTTP request.
I'll probably stick to my Session+cookie+database system for now, but what of these other things mentioned here? They seem mysterious to me. Is a further combination possible to make things even more secure, or would that just be overkill?
My main concern is that possible, the system of Session+Cookie+Database which I use, might have a flaw in it.
We use DNN (ASP based CMS) and develop modules. We use ViewState a lot for storing little things, like row id's. View state doesn't require that cookies are enabled on the browser, but for large objects like datasets, reading and writing and transferring can get heavy. So we store the row id and requery the table when the postback happens.
The query string is really the thing when you are directing users between different pages. For the most part, we are encrypting this now with a utility built into DNN. I would recommend that to stop users that tweak the query string for kicks.
Caching is your scalability thing. It takes a bit more programming work (you always have to be ready to reload), and using it too much puts a memory load on your IIS server, but for data lists that are used a lot, it can really speed things up. I rarely use it for user-specific data.
All in all, these constructs are heavier than you are used to in php, but they will make your programming life much easier.
Using Session (either in memory or via a database) and Cookies for handling and persisting authentication and user details is usually the standard approach in an ASP.NET website.
Application state and Caching provide similar functionality in that it allows you to store data that is accessible to the whole application, not just a specific session, at any time however Caching is the preferred approach as it give you some extra features that allows you to control when the data is refreshed via the CacheDependency object and prioritise its lifetime in the event of memory running low. If you have some data that is expensive to retrieve from a database and relevant to all users of your site then you would store it here i.e. a list of values for a drop down list.
Viewstate persists page data between requests and is typically used to hold your web control values however custom values can be added if desired and relevant. The caveat with this is that these values are encrypted and sent a part of the page response and returned via the request to this can add a large amount of overhead to your page size if you are not careful.
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.
What's the best way to authenticate and track user authentication state from page to page? Some say session state, some say cookies?
Could I just use a session variable that has the ID of the user and upon authentication, instatiate a custom User class that has the User's information. Then, on every page, verify the session variable is still active and access basic user data from the User object?
Any thoughts? Any good examples?
The problem with favoring sessions over cookies for 'security' is that sessions USE cookies to identify the user, so any issue with cookies is present with sessions.
One thing to keep in mind with the use of Sessions is data locality. If you plan to scale to more than one webserver at any point, you need to be very careful storing large amounts of data in the session objects.
Since you are using .NET, you will basically have to write your own session store provider to handle this, as InProc won't scale past 1 server, the DB provider is just a bad idea entirely (The whole point is to AVOID DB reads here while scaling, not add more), and the StateServer has a lot of capacity issues. (In the past, I have used a memcached session store provider with some success to combat this issue).
I would google for signed cookies and look into using that instead of either regular cookies or sessions. It solves a lot of the security concerns, and removes the locality issues with sessions. Keep in mind they come back and forth on every request, so store data sparingly.
There's no perfect way to do it. If you store it in a cookie you'll take flak that cookies can be stolen. If you store it in the session you'll take flak because sessions can be hijacked.
Personally, I tend to think a session is a little more reliable because the only thing stored on the client is a session key. The actual data remains on the server. It plays the cards a little closer to the chest, if you will. However, that's just my preference, and a good hacker would be able to get past shoddy security regardless.
No matter what you do, don't try to implement this yourself. You'll get it wrong. Use the authentication system provided by your specific platform. You also need to make sure you have adequate security precautions protecting the authentication token.
I dont know if its THE BEST way to do it, but we are comfortable with the way we do it.
we have a custom user object that we instantiate when the user authenticates, we then use Session to maintain this object across the application.
In some application we combine it with the use of cookies to extend the session continuously.
Cookies and Sessions by themselves are not truly sufficient. They are tools to use to track the user and what they do, but you really need to think about using a database to persist information about the user that can also be used to secure the application.
Sessions are Cookies...