Sunday, January 18, 2009

Static Variables and their implications in ASP.Net websites

Are you using static variables in your ASP.Net websites? Do you know the implications that they have on your website? (Especially the security implications?)

Well, first off go visit this ASP.Net site which will demonstrate the dangers of using static variables in your website: http://www.aggregatedintelligence.com/Samples/StaticsDemo/default.aspx

There are 2 sets of text boxes. The first one stores values using static variables, the second set stores variables using the Session object. Try and type in each box and update the values using the buttons. Now try closing your browser and then go back to the site. Also, try and access the site from a different browser. See anything interesting? The first set of boxes will either end up showing you values that you typed in during a different session (if you closed and reopened the browser) or values from a different computer (if you closed and the reopened the page from a different computer) or values from another user (if another user changed the values while you were looking at the page).

This is a BAD code smell and here is a little bit about why it might get used and why you should not use it and what are the alternatives.

Why do developers use static variables? Typically, it is used to persist values in class member variables across post-backs. Normally, if you create a member variable and store a value in it – you will find that the value gets erased after a post-back (such as that caused by a button click event)

Why should you not use static variables? Static variables are global variables for that page. This means that they will hold their value across post-backs (which is the behavior the developer wants), but the value in that variable is also available to all users accessing the website!!!! Think about this for a minute: if you use a static variable to store the current user's login-id, or security level, or a password, then that value becomes available to anybody else who accesses that page. If your code is badly written – it is conceivable that the other user can gain access to data that they should not have access to. There is another problem, that can lead to weird behavior in your website. Static variables are not thread-safe. Each user that accesses your website is running within a separate thread. If 2 people do some action that tries to update the variable at the exact same time – you can get weird issues – such as web-site locking up. Basically, it boils down to the fact that the life-time of a static variable is for the life of the application (actually it is more like for the life time of the process hosting the website, but that is a detail we can gloss over for this topic). And furthermore, the scope of the static variable is page/application wide and NOT session specific. And those 2 are extremely important details to remember when you use a static variable in your ASP.Net web application.

Static variables should smell bad to you ALWAYS! (in an ASP.Net application that is - but read caveat below)

What should you use instead of a static variable? There are 3 places available to you to store values that persist across page post-backs: Session – use this when you need access to the variables value across multiple pages ViewState – use this when you need access to the variable only within the current page. (Don't use ViewState to store objects that can potentially get very large, such as DataSets, as this information gets serialized and sent to the client browser during each round-trip. Cache – One more location that you can store user specific information.

Caveat: What if you want to store a value that should be accessible across the website? There are always cases where one would want to set a variable that is then accessible across the website and all users that use that site. (A good example for such a variable is one that flags if the website is available or not, depending on which – logins to the site are allowed or denied). (Update: 02-24-2009: I have removed the recommendation of using ONLY the application object, this is because the Application object was made to provide an easy route to migrate old ASP apps. Using static variables - sensibly - can lead to more performant code). One can use the Application object instead of static variables, which is similar to Session object, only it is available to the entire application. Only thing to remember is that one should use locks on the static variables in the Application container to make it thread-safe (otherwise you might see weird run-time behavior and hours spent trying to debug them). This is not an issue with non-static variables stored in the Application object. When the data that you are storing is not temporary and not user specific, then you can use a static variable to store that information. A lot of the data used by your web-site is already static - one such example is the ConfigurationManager and this makes sense: the Configuration properties for your web-site apply site wide and are not user specific. Static variables are more performant than the Application object and one should keep this in mind when they are trying to decide which route they wish to take. (Also, using a static variable will typically lead to more readable code when compared to using the Application object).

Here is a good article on how to use Application object: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

The bottom line is that: never use a static variable to store user-specific data.

13 comments:

Anonymous said...

Rao,

I appreciate your article on the subject. Quite informative. But i think asp.net has a lot to do on the cache front. if you put variable in asp.net cache, it terribly lacks lacks reliability. I suggest giving distributed cache scenario a try in this case. Caching solutions like velocity or ncache etc.

Ostati said...

Thanks for the article, but I'm tempted to say that all of the .net configuration classes (ie we.config section handlers) are stored static, and so are mine... However, you are 100% absolutely right that one should never keep temporary data in a static variable, and instead, they should consider alternatives...

Anonymous said...

That was a good article, but I use static very freely for the postbacks and it never gave me any problem. I have a login system where a user logs in to see his own contents. I have repeated this with several users. I have a hint that it has to do something with appDomain, virtual Tables etc but no concrete solution.
If any of you gentlemen has any idea of such behavior please post me to : premanshu_love@yahoo.com

Anonymous said...

Very good article.

Congratulations from spain!
Jose

Anonymous said...

Thank you for this great article. I was screwed by static thingy today :(

Anonymous said...

Good information. Wish I had read it about a month ago; would have saved me a lot of work. But I can see how it may come in handy sometime in the future.

Anonymous said...

I was screwed up by my static thingy today too... and i wasnt aware of this concept. Very information. Although I would have appreciated example snippets on the 3 alternatives that you suggested.
Thanks anyways...

Unknown said...
This comment has been removed by a blog administrator.
suresh said...

The link is not working ..Appreciated if you can help.
Thanks

Raj Rao said...

Suresh,
the site is down and it will probably take me a little while to get it back up.
If you send me your email - I can send you the code.

Pooja said...

i understand not using static variable for user specific information but what if i create a static property to store some data that i need to use on that page many times...i believe view state can become large making ur page slow

Raj Rao said...

Pooja one option: - if its user specific information - then use Session and if its not user specific information - then use the Cache.

Wun Love said...

Nice article. You really explained it in laymans terms. I'm still unclear as to what three good uses for a static variable would be on a website?