Share session (asp->asp.net) security - asp.net

I need to share session in order to pass data from asp page to aspx. The solutions I've found:
• Pass data through hidden form (link)
• Pass data through database (link)
I've tried method with form and it worked fine (after some modification). Now I'm trying method with database. First method is easier imho, so I wonder if the second method is more secure (and preferable) than the first one?
And what potential problems exist with these methods?

The first solution is definitely less secure since you're sending session data to the client and then receiving it back. That means that it's possible for someone on the client side to modify the data they post back to your page. This removes one of the best things about sessions, that only the programmer controls what's in them. In a way, the first method is similar to using cookies. As for the second method, it may be more difficult but I would definitely recommend it over the first.

If the session is encrypted I think you will fine. ASP.NET has the option of storing the session in a database and URL querystring to get around users not having cookies enabled. Your solutions sound similiar.

Microsoft outlines a method to share session state between ASP classic and ASP.NET using SQL Server to store the session here: http://msdn.microsoft.com/en-us/library/aa479313.aspx

Related

Mixing JQuery Ajax with ASP.NET : is there any security risk

I am using jQuery with ASP.NET in a project. Instead of using ASP.NET Ajax, I am using jquery's ajax functions. Is there any security risk if I do that? I mean, since I am using jquery's ajax calls, no view state information will be passed to the server so that it can verify the page's authenticity (though it saves a lot of bandwidth..).
I would also like to know what is the best/good practice here.
Microsoft has included Jquery in their Visual Studio releases (see: http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx)
If there was a big security risk they probably wouldn't have done that ;)
As with al webapplications never trust the input you recieve. It doesn;t matter if you're working with ASP.Net AJAX, Jquery or any other library. Web requests can always be spoofed. Therefor always sanitize the input you recieve and make sure that the user is authenticated (ASP.Net forms authentication uses cookies and not viewstate).
Make sure that you validate all user input. And post basic authentication information to your Web Services (jQuery.ajax has a data parameter), so that no one can use the services without being a part of the system.
Passing along a session GUID and thus providing the Web Service with full authentication, is enough security for most applications (in addition to normal security checks such as input validation). You may specify closer what security level your application needs.
I use the same practice on many case - jQuery ajax on aspx pages
You can check 3 thinks (select 1-2 of them) and be sure that none can create troubles on your site.
Send all the post data encrypted (if you can).
Send hash value with the post data - and check for the correction of the hash (if you can).
Check that the calls is coming from your host on url.
eg, you have a page 'http://www.yourhost.com/askforajax.aspx',
check if the url starting with the 'http://www.yourhost.com/'
The hash I mean here, must be your implimation of hash or crc check or what ever you like you can call it.
here is a real ajax call from my pages
doSomeWork.aspx?plist=36&pslst=1&e=1202638085&er=12585795
The last 2 parametres are check parametres.
Also inside the the ajax page that make the calculations check every parameter for be correct.
I also check some other thinks in some cases, for example if a user press a button that make a change somewhere this user must have cookies enabled, so I check if the users cookie hash is the same.
For the url check
I belive that the Request.ServerVariables["HTTP_REFERER"], can do the work of checking from where the request come from.
HTTP_REFERER Returns a string containing the URL of the page that referred the request to the current page using an tag. If the page is redirected, HTTP_REFERER is empty
Hope this help you.

Stop Direct Page Calls to Ajax Pages

Is there a "clever" way of stopping direct page calls in ASP.NET? (Page functionality, not the page itself)
By clever, I mean not having to add in hashes between pages to stop AJAX pages being called directly. In a nutshell, this is stopping users from accessing the Ajax pages without it coming from one of your websites pages in a legitimate way. I understand that nothing is impossible to break, I am simply interested in seeing what other interesting methods there are.
If not, is there any way that one could do it without using sessions/cookies?
Have a look at this question: Differentiating Between an AJAX Call / Browser Request
The best answer from the above question is to check for a requested-by or custom header.
Ultimately, your web server is receiving requests (including headers) of what the client sends you - all data that can be spoofed. If a user is determined, then any request can look like an AJAX request.
I can't think of an elegant method to prevent this (there are inelegant and probably non-perfect methods whereby you provide a hash of some sort of request counter between ajax and non-ajax requests).
Can I ask why your application is so sensitive to "ajax" pages being called directly? Could you design around this?
You can check the Request headers to see if the call is initiated by AJAX Usually, you should find that x-requested-with has the value XMLHttpRequest. Or in the case of ASP.NET AJAX, check to see if ScriptMAnager.IsInAsyncPostBack == true. However, I'm not sure about preventing the request in the first place.
Have you looked into header authentication? If you only want your app to be able to make ajax calls to certain pages, you can require authentication for those pages...not sure if that helps you or not?
Basic Access Authentication
or the more secure
Digest Access Authentication
Another option would be to append some sort of identifier to your URL query string in your application before requesting the page, and have some sort of authentication method on the server side.
I don't think there is a way to do it without using a session. Even if you use an Http header, it is trivial for someone to create a request with the exact same headers.
Using session with ASP.NET Ajax requests is easy. You may run into some problems, like session expiration, but you should be able to find a solution.
With sessions you will be able to guarantee that only logged-in users can access the Ajax services. When servicing an Ajax request simply test that there is a valid session associated with it. Of course a logged-in user will be able to access the service directly. There is nothing you can do to avoid this.
If you are concerned that a logged-in user may try to contact the service directly in order to steal data, you can add a time limit to the service. For example do not allow the users to access the service more often than one minute at a time (or whatever rate else is needed for the application to work properly).
See what Google and Amazon are doing for their web services. They allow you to contact them directly (even providing APIs to do this), but they impose limits on how many requests you can make.
I do this in PHP by declaring a variable in a file that's included everywhere, and then check if that variable is set in the ajax call file.
This way, you can't directly call the file ever because that variable will never have been defined.
This is the "non-trivial" way, hence it's not too elegant.
The only real idea I can think of is to keep track of every link. (as in everything does a postback and then a response.redirect). In this way you could keep a static List<> or something of IP addresses(and possible browser ID and such) that say which pages are allowed to be accessed at the moment from that visitor.. along with a time out for them and such to keep them from going straight to a page 3 days from now.
I recommend rethinking your design to be sure that this is really needed though. And also note IPs and such can be spoofed.
Also if you follow this route be sure to read up about when static variables get disposed and such. You wouldn't want one of those annoying "your session has expired" messages when they have been using the site for 10 minutes.

asp.net server side viewstate without sessions

So I've done my best to minimize my viewstate on my ASP.net ajax application, http compression, disabling viewstate in hidden fields, but would like to go further. So after researching it seems that there are two approaches
a) use the ASP.net 1.x way which uses LoadPageStateFromPersistenceMedium
b) or use the ASP.net 2.x way SessionPageStatePersister
So B doesn't look good because if I understand it correctly the viewstate would be linked to the session id, and since my session can expire for any number of reasons I want don't want this.
So what's the best approach to saving viewstate on the server that does depend on sessions?
If it's LoadPageStateFromPersistenceMedium and uses hidden fields, then how do I inject a hidden field with a random id into a page?
How do I determine when it's time to clear viewstate files on the server?
I think you should seriously consider the Session option. It's optimal on resources and even if the Session expires if your Auth mechanism is alighed to session timeout it's not an issue.
http://professionalaspnet.com/archive/2006/12/09/Move-the-ViewState-to-Session-and-eliminate-page-bloat.aspx
As a fallback you could implement a Page base that puts the Session ID into the ViewState, checks it on postback and if it's different than does some action to recover.
The only other option you have would be to create your own PageAdapter that uses the DB or some other data store.
How about trying Flesk ViewState Optimizer?
Has several options including storing in session, in database, etc.

Is there conditional caching in ASP.NET?

Is there a built-in asp.net way to conditionally serve pages, for example I want the following logic:
If there is a session data I generate
a page, if there is no session data I
serve the cached page.
I am only interested in knowing about a built-in asp.net mechanism for this. If it does not exist I am probably going to simply cache my page manually and decide whether to serve it or not for each request, based on the session data availability.
I don't think there is built-in support (like varyByParam) for generating fresh output for users with Session Data.
As you suggest, I would recommend manually caching the pages. I would probably determine the user's Session state in the PreRequestHandlerExecute event handler in the Global.asax and then maybe set:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
At the risk of karmabombing, I really don't like this approach to caching.
For me if a GET request is made, then a server should respond to that in good faith. Caching at a page level should be controlled by http headers because the primary goal is not to get the redundant request at all - you don't want to allocate server/bandwidth resources full stop.
Caching objects which are resources involved in making up a page I can totally get behind, but I can't see great arguments for caching a page wholesale.
Respect the headers.
You might want to look at the substitution control (Link) new in .NET 2.0, however it might not be exactly what you are after.

ASP.Net Session

I am wanting to store the "state" of some actions the user is performing in a series of different ASP.Net webforms. What are my choices for persisting state, and what are the pros/cons of each solution?
I have been using Session objects, and using some helper methods to strongly type the objects:
public static Account GetCurrentAccount(HttpSessionState session)
{
return (Account)session[ACCOUNT];
}
public static void SetCurrentAccount(Account obj, HttpSessionState session)
{
session[ACCOUNT] = obj;
}
I have been told by numerous sources that "Session is evil", so that is really the root cause of this question. I want to know what you think "best practice", and why.
There is nothing inherently evil with session state.
There are a couple of things to keep in mind that might bite you though:
If the user presses the browser back button you go back to the previous page but your session state is not reverted. So your CurrentAccount might not be what it originally was on the page.
ASP.NET processes can get recycled by IIS. When that happens you next request will start a new process. If you are using in process session state, the default, it will be gone :-(
Session can also timeout with the same result if the user isn't active for some time. This defaults to 20 minutes so a nice lunch will do it.
Using out of process session state requires all objects stored in session state to be serializable.
If the user opens a second browser window he will expect to have a second and distinct application but the session state is most likely going to be shared between to two. So changing the CurrentAccount in one browser window will do the same in the other.
Your two choices for temporarily storing form data are, first, to store each form's information in session state variable(s) and, second, to pass the form information along using URL parameters. Using Cookies as a potential third option is simply not workable for the simple reason that many of your visitors are likely to have cookies turned off (this doesn't affect session cookies, however). Also, I am assuming by the nature of your question that you do not want to store this information in a database table until it is fully committed.
Using Session variable(s) is the classic solution to this problem but it does suffer from a few drawbacks. Among these are (1) large amounts of data can use up server RAM if you are using inproc session management, (2) sharing session variables across multiple servers in a server farm requires additional considerations, and (3) a professionally-designed app must guard against session expiration (don't just cast a session variable and use it - if the session has expired the cast will throw an error). However, for the vast majority of applications, session variables are unquestionably the way to go.
The alternative is to pass each form's information along in the URL. The primary problem with this approach is that you'll have to be extremely careful about "passing along" information. For example, if you are collecting information in four pages, you would need to collect information in the first, pass it in the URL to the second page where you must store it in that page's viewstate. Then, when calling the third page, you'll collect form data from the second page plus the viewstate variables and encode both in the URL, etc. If you have five or more pages or if the visitor will be jumping around the site, you'll have a real mess on your hands. Keep in mind also that all information will need to A) be serialized to a URL-safe string and B) encoded in such a manner as to prevent simple URL-based hacks (e.g. if you put the price in clear-text and pass it along, someone could change the price). Note that you can reduce some of these problems by creating a kind of "session manager" and have it manage the URL strings for you but you would still have to be extremely sensitive to the possibility that any given link could blow away someone's entire session if it isn't managed properly.
In the end, I use URL variables only for passing along very limited data from one page to the next (e.g. an item's ID as encoded in a link to that item).
Let us assume, then, that you would indeed manage a user's data using the built-in Sessions capability. Why would someone tell you that "Session is evil"? Well, in addition to the memory load, server-farm, and expiration considerations presented above, the primary critique of Session variables that they are, effectively, untyped variables.
Fortunately, prudent use of Session variables can avoid memory problems (big items should be kept in the database anyhow) and if you are running a site large enough to need a server farm, there are plenty of mechanisms available for sharing state built in to ASP.NET (hint: you will not use inproc storage).
To avoid essentially all of the rest of Session's drawbacks, I recommend that implement an object to hold your session data as well as some simple Session object management capabilities. Then build these into a descendent of the Page class and use this descendent Page class for all of your pages. It is then a simple matter to access your Session data via the page class as a set of strongly-typed values. Note that your Object's fields will give you a way to access each of your "session variables" in a strongly typed manner (e.g. one field per variable).
Let me know if this is a straightforward task for you or if you'd like some sample code!
As far as I know, Session is the intended way of storing this information. Please keep in mind that session state generally is stored in the process by default. If you have multiple web servers, or if there is an IIS reboot, you lose session state. This can be fixed by using a ASP.NET State Service, or even an SQL database to store sessions. This ensures people get their session back, even if they are rerouted to a different web server, or in case of a recycle of the worker process.
One of the reasons for its sinister reputation is that hurried developers overuse it with string literals in UI code (rather than a helper class like yours) as the item keys, and end up with a big bag of untestable promiscuous state. Some sort of wrapper is an entry-level requirement for non-evil session use.
As for "Session being evil" ... if you were developing in classic ASP I would have to agree, but ASP.NET/IIS does a much better job.
The real question is what is the best way to maintain state. In our case, when it comes to the current logged in user, we store that object in Session, as we are constantly referring to it for their name, email address, authorization and so forth.
Other little tidbits of information that doesn't need any long-term persistence we use a combination of cookies and viewstate.
When you want to store information that can be accessed globally in your web application, a way of doing this is the ThreadStatic attribute. This turns a static member of a Class into a member that is shared by the current thread, but not other threads. The advantage of ThreadStatic is that you don't have to have a web context available. For instance, if you have a back end that does not reference System.Web, but want to share information there as well, you can set the user's id at the beginning of every request in the ThreadStatic property, and reference it in your dependency without the need of having access to the Session object.
Because it is static but only to a single thread, we ensure that other simultaneous visitors don't get our session. This works, as long as you ensure that the property is reset for every request. This makes it an ideal companion to cookies.
I think using Session object is OK in this case, but you should remember Session can expire if there is no browser activity for long time (HttpSessionState.Timeout property determines in how many minutes session-state provider terminates the session), so it's better to check for value existence before return:
public static Account GetCurrentAccount(HttpSessionState session)
{
if (Session[ACCOUNT]!=null)
return (Account)Session[ACCOUNT];
else
throw new Exception("Can't get current account. Session expired.");
}
http://www.tigraine.at/2008/07/17/session-handling-in-aspnet/
hope this helps.
Short term information, that only needs to live until the next request, can also be stored in the ViewState. This means that objects are serialized and stored in the page sent to the browser, which is then posted back to the server on a click event or similar. Then the ViewState is decoded and turned into objects again, ready to be retrieved.
Sessions are not evil, they serve an important function in ASP.NET application, serving data that must be shared between multiple pages during a user's "session". There are some suggestions, I would say to use SQL Session management when ever possible, and make certain that the objects you are using in your session collection are "serializable". The best practices would be to use the session object when you absolutely need to share state information across pages, and don't use it when you don't need to. The information is not going to be available client side, A session key is kept either in a cookie, or through the query string, or using other methods depending on how it is configured, and then the session objects are available in the database table (unless you use InProc, in which case your sessions will have the chance of being blown away during a reload of the site, or will be rendered almost useless in most clustered environments).
I think the "evil" comes from over-using the session. If you just stick anything and everything in it (like using global variables for everything) you will end up having poor performance and just a mess.
Anything you put in the session object stays there for the duration of the session unless it is cleaned up. Poor management of memory stored using inproc and stateserver will force you to scale out earlier than necessary. Store only an ID for the session/user in the session and load what is needed into the cache object on demand using a helper class. That way you can fine tune it's lifetime according to how often that data us used. The next version of asp.net may have a distributed cache(rumor).
Session as evil: Not in ASP.NET, properly configured. Yes, it's ideal to be as stateless as possible, but the reality is that you can't get there from here. You can, however, make Session behave in ways that lessen its impact -- Notably StateServer or database sessions.

Resources