I'm using a session to hold a class. In the class are things like first name, last name, Message.
I have information in the first name and last name and on each page i go to i can retrieve that information. Now after the session is created, if i give the message property a value and destroy the session and recreate it, all three properties show up as being populated.
However, when i do a response.redirect the message property is lost but the other two are still there.
I've tried doing response.redirect("PageName.apsx",false) but that has not helped my cause.
Why would the message property be dropped?
This is a bit hard to follow. You:
create a session and assign the message property.
you destroy the session (why?) btw I never trust a session kill before a redirect is complete because the client still retains a session id cookie until the request is complete.
magically all three properties are still in the session (you didnt mention when you assign first/last to the session
you redirect and the first two (which you never state where they are set) are lost.
It sounds as though you are creating a new session and setting the message. However the client is sending over the old session id which the server still considers valid. Without seeing how you are killing the session and which session ids are being set/sent in the response/request headers its hard to see (plus no code provided)
Related
I'm wondering if ServletResponse.reset() is the extra step I need to block non-logged-in users from accessing servlets, or if there are risks or downsides to it.
Background:
The way my website works, initially users can only see certain pages after they create an account and login with those credentials. The problem I was initially having was, even though I used session.invalidate(), when a user logged-out, they could re-send the request (for example, via the back button) and were able to access restricted contents from the unauthorized state. Assuming the session is expired, as per above, I'm not sure how that's even possible or what can properly be done to prevent it.
Through experimentation, as a workaround, I tried ServletResponse.reset(), and that seemed to resolve it, but I don't understand why it works, and hence, I'm not confident it is a robust viable solution.
My specific questions are:
Is resetting the response buffer (including header and http status code) a safe or recommended practice, or is there a better way to do it?
How can I manage logging in with the session object as opposed to using a session cookie?
I don't think ServletResponse.reset() will hurt anything but it isn't standard operating procedure and it shouldn't be necessary. Just make sure you're doing the right things both invalidating and validating sessions.
Invalidating session:
Call session.invalidate() to remove session attributes bound to a session, but also be sure your code explicitly removes it's own stale references to the previous session state. Session cookies can be explicitly removed by locating the cookie with exact matching criteria and setting its maximum age to 0.
Validating session:
When authenticating, you can check whether getSession(false) returns null to determine if there is an active session. If so you can invalidate it then, and you can also check request.isRequestedSessionIdValid(), or explicitly check for the presence any specific attributes you've used in your session management scheme. That will let you verify the state of the session properly.
From the JavaDocs:
ServletResponse
void reset()
Clears any data that exists in the buffer as well as the status code and headers. If the response has been
committed, this method throws an IllegalStateException.
void invalidate()
Invalidates this session then unbinds any objects bound to it.
ServletRequest
boolean isRequestedSessionIdValid()
Checks whether the requested session ID is still valid.
HttpSession getSession(boolean create)
Returns the current HttpSession associated with this request or, if there is no current session and create is true,
returns a new session. If create is false and the request has no valid HttpSession, this method returns null.
To make sure the session is properly maintained, you must call this method before the response is committed.
is using cookies to maintain session integrity and is asked to create a new session when the response is
committed, an IllegalStateException is thrown.
I understand that Session object is used to store data per session. I did the following experiment:
Open browser and visit an aspx page A, which saves some data to Session object.
Keep the browser open and open another tab to visit an aspx page B which display the session data. And it displayed just as I stored in step 1.
I close the browser and re-visit the page B, the stored data is gone.
From 3, it seems server side somehow detect that I (the client side) has terminated a session. But as I checked with Fiddler, there's no bits sent to the server when I close the browser in step 3.
So how could the ASP.NET application possibly know my step 3 request is for a new Session?
And how is session defined? Do different tabs always belong to the same session?
ADD 1
Although the session data can be displayed in page A and page B, the session IDs displayed in them are different. Why?
Correct
The session id in page A and page B are the same. I am not using InPrivate browsing.
ADD 2
There's indeed a Cookie for session ID:
ASP.NET_SessionId=lmswljirqdjxdfq3mvmbwroy; path=/; domain=localhost; HttpOnly
It was set when a POST request is responded.
So I did another experiment, I close the browser (Fire Fox) and as expected, the Cookie no longer exist. I manually create the cookie in hope of "the faked Cookie could bring back the old session." But Fiddler indicates that the manual cookie didn't get sent at all.
Fiddler says:
This request did not send any cookie data.
So is it possible to fake a cookie and restore an previous session?
And how long does a session live on server?
When the server starts a new session, it generates a new identifier for the session. The session data is stored under this identifier / key in your session provider (can be in-memory, in SQL Server or something else entirely, depending on your configuration - this is usually configured in web.config).
At the same time, the server sends a cookie to your browser (at least in the default setup). This cookie contains the identifier for your session. That is how the server can correlate your requests to your particular session: in every request, your browser will send the session cookie along. The server retrieves the identifier from the cookie and looks up your session data using the identifier.
The session cookie is non-persistent, which means that the cookie will be deleted when the browser is closed. That is why it looks like the session was deleted: the session data still exists on the server, but because the session cookie has been deleted, the browser won't send along a session cookie, so the server will consider this to be the beginning of a new session, create a new session identifier etc. Thus, the server doesn't really know when a session ends, it just knows when a session begins. That is why, in the default SQL Server-backed setup, a scheduled job will purge inactive sessions - otherwise the session data would linger in the database forever.
For more on sessions, using sessions without cookies, session configuration, providers etc., see MSDN.
As to whether sessions are shared between browser tabs: this really comes down to whether cookies are shared between tabs. I think cookies are shared across tabs in all major browsers and I would assume it would be rather confusing if they weren't, but there is nothing preventing someone from creating a browser where cookies aren't shared across tabs.
EDIT 1
If you delete the session cookie, you could in theory recreate your session by recreating the cookie. This is not a security issue per se, because you are recreating data you already have access to. However, if someone else were to recreate your session cookie, that would be a security issue. You can google "ASP.NET session hijacking" if you want to look into this.
EDIT 2
The session basically lives on the server until something purges it. Thus, the lifetime of the session depends on where you store it. If you store it in memory, the session will be deleted when the application is recycled (could be because you recycle the app in IIS or because the server is restarted). If you store it in SQL Server, the session data will live until a job deletes it because it hasn't been accessed for a while (sorry, I don't remember the details, but you can probably google them). If you store your session data in Azure table storage, they will likely never be purged.
Note
Two important details of ASP.NET session state are often overlooked:
When the session is stored outside the process (say, in SQL Server), the data you want to store must be serializable.
To prevent race conditions when accessing the session data, requests accessing the session will be serialized, that is, they will not execute concurrently.
Further details may be found in the MSDN article "Underpinnings of the Session State Implementation in ASP.NET"
This article provides more details about ASP.NET Session (http://msdn.microsoft.com/en-us/library/vstudio/ms178581(v=vs.100).aspx)
The idea is simple.
When you visit a page, a session ID is generated and set as a cookie. A timer is started for that session ID too.
As you keep coming back, the timer is reset. If you wait long enough before requesting another page, the timer will expire and your session will not be valid. At that point a new session will be generated.
To Answer your questions:
If you open multiple tabs, they will "share" the session. Because your browser is sending the session cookie from all those tabs.
However, if you open Firefox and Chrome. These two browsers will not share the session. Since, they don't share cookies.
When you close your browser, your session is still valid. And if you visit a page on the site before the session has expired, you will not get a new session. That is why, it is suggested to always log out. This way the site knows that you're leaving and it will destroy the session on your behalf.
Q: Although the session data can be displayed in page A and page B, the session IDs displayed in them are different.
A: Are you sure? The session ID should be the same for all pages. It will be different if you access page A from one browser and Page B from another browser.
ADD2
It is possible your browser's setting is to destroy cookies on windows close. Please double check that in options it's set to remember history.
Cookies can be forged. If an attacker can get the session ID, they can forge a cookie at their end. I'm not sure if Fiddler allows you to create a cookie manually. You will need to dig through the docs. Or maybe someone else here can answer this questions.
I have an asp.net web app which uses state server to store its sessions. When we change a type of something which is stored in the session, all users with active sessions got error, beacuse the "old session" contains insrtances of "old type".
I thought that the simplest way to overcome this problem would be to restart the state server, therefor get rid of all sessions. However, this was proffed to be a naive approach. Sessions seems to be still active (users with session old cookie are still capable of working). Is there some other way to force the session state server throw away all sessions, so that old users will be assigned new session? It is ok if they would be forced to authenticate again.
Or is there some other (better) way of abandoning all sessions? Ideally not programmaticaly, but something our admin could do?
Programmatical approach woudl be maybe calling Session.RemoveAll in Application_End would solve the issue, bu is this standard approach?
Where are session stored in state server if not in memory (which should cease to exist on restart)?
I have found two SO questions which are relevant:
Clear all sessions on application start - this is rather incomplete programmatical solution
How to clear SQL session state for all users in ASP.NET - this is exactly what I would needed if I had had an sql server approach of storing of session data
Ok, So it seems so (after a bit of experimenting), that restarting of the session state server throw away all data in the session.
The users still have their session ID valid after restart though, which got me originally thinking that the session is not thrown away.
I guess that if the session id sent from a user is not assigned to some existing session, than it is reused for the new one, so user still operates with the same id. Nevertheless, the data in session are cleared.
This doesn't directly answer your question but a clean programmatic workaround could be to wrap access to Session and try to be smart and detect issues:
// example
public string SomethingWrapper
{
try
{
return (string)Session["something"];
}
catch
{
return "defaultvalue";
}
}
This should work for value objects and composite objects too. If the deserializer fails for a compound object, you get an exception and have a chance to return just anything, a default value for example. Or you can recreate the value and put it back into session container.
I've implemented a custom session state provider for Oracle in my application. It seems to run smoothly (without errors!), but I'm having trouble retrieving some Session variables when I redirect to another page. But it doesn't happen all the time.
When the Session starts, I load a User object into Session. It stays there, because when the user gets to the starting page (and is authenticated), the app still recognizes him. It has no problem retrieving the User object from Session.
But if I pass a value into Session on one of my pages inside the app, then redirect to another page in order to utilize that Session variable, the new page retrieves null from the same named Session variable. Using the Visual Studio Watch window, I can actually see its value change from "100" (or whatever) to null. I don't get it.
The session provider seems to be working correctly because as I said, I'm able to persist some variables. Does someone know what the reason might be for Session to "lose" a value? Thanks.
If you are doing a response.redirect in the page, that can cause the thread to abort before the Session is written back to the database.
Our asp.net 2.0 application has a very long process (synchronized) before sending response back to client. I observed that a second request, exactly same the initial one, was sent after client IE8 waited response for a long period of time while our application was still processing the first request.
I use page session with predefined key to store a flag when the initial request arrives and then starts long process while client IE waits for the response, so if second request comes in, our application checks the session value. After our application sets the session flag and starts processing, I use Fiddler “Abort Session” to abort the initial request, right away the second request (same as the first one) is sent automatically, but session value set earlier seems no longer exist.
Any thoughts?
When the second request comes in during your ongoing process isn't it overwritting your current request's value since it is only storing one item? Assuming both requests are coming in under the same session.
Maybe consider storing a list of items so that you can add the second item to your list of flags and then find any previous items and delete them.
Maybe kill the request currently in the session before starting the second requests session?
I don't really understand your problem / solution all that well but hopefully that helps.
Edit based on your comment:
If it no longer exists it's probably due to your session timing out and wiping the values so the second one wouldn't be able to access it. Is the second connection coming in under the exact same session? Compare the Session IDs in both cases. Also check your timeout.
You could also store this information in your application Cache that has a real long expiry. Have a dictionary with the key being the session ID or even the user if you only want one process per user and then store your value. This when the second request comes in by the same user, you will be able to find it regardless of session ID. Just make sure you are clearing once your process is complete.