SessionID is still the same after Session.Abandon call - asp.net

I'm writing some logging code that is based on SessionID...
However, when I log out (calling Session.Abandon), and log in once again, SessionID is still the same. Basically every browser on my PC has it's own session id "attached", and it won't change for some reason :/
Any ideas what is going on?
My Session config looks like this:
<sessionState
mode="InProc"
timeout="1" />
Thanks, Paweł

Check this article which explains the process on session.abandon
http://support.microsoft.com/kb/899918
Taken from above link -
"When you abandon a session, the session ID cookie is not removed from the browser of the user. Therefore, as soon as the session has been abandoned, any new requests to the same application will use the same session ID but will have a new session state instance"

This is a default behavior by design as stated here:
Session identifiers for abandoned or expired sessions are recycled by default. That is, if a request is made that includes the session identifier for an expired or abandoned session, a new session is started using the same session identifier. You can disable this by setting regenerateExpiredSessionId attribute of the sessionState configuration element to true
You can disable this setting as mentioned above.
EDIT: Setting regenerateExpiredSessionId attribute to true works only for cookieless sessions. To overcome your problem, you can consider to implement a custom class that inherits SessionIDManager class. You can get information about that here and here.

This is an old post but if someone is still looking for answers, here is a complete and step-by-step solution on how to achieve a clean logout with a new session ID every time.
Please note this article applies to cookie-enabled (cookieless=false) sites only.
Step (1) Modify your web.config file & add "regenerateExpiredSessionID" flag as under -
<sessionState mode="InProc" cookieless="false" regenerateExpiredSessionId="true" />
Step (2) Add the following code in your logout event -
Session.Clear();
Session.Abandon();
Response.Cookies.Add(New HttpCookie("ASP.NET_SessionId", ""));
Response.redirect(to you login page);
Step (3) Add the following code in your login page's page_load event -
if(!IsPostBack)
{
Session.Clear();
Session.Abandon();
}
Step 2 and 3 serve one IMPORTANT purpose. This code makes sure a brand new Session ID is generated after you click the "Login" button. This prevents Weak Session Management (Session Fixation vulnerability) which will likely be spotted during a 3rd party Penetration Testing of your site.
Hope this helps.

Here's what worked for me, the only caveat is that this code need to be separated from your login routine.
Response.Cookies("ASP.NET_SessionId").Expires = DateTime.Now.AddYears(-30)
It will not take effect until the page is finished loading. In my application I have a simple security routine, that forces a new ID, like this:
if session("UserID") = "" then
Response.Cookies("ASP.NET_SessionId").Expires = DateTime.Now.AddYears(-30)
Response.Redirect("login.aspx")
end if

You may explicitly clear the session cookie. You should control the cookie name by configuration and use same name while clearing.
Edit:
Clearing session cookie when session is abandoned will force ASP.NET to create new session & sessionid for next request. BTW, yet another way to clear the session cookie is to use SessionIDManager.RemoveSessionID method.

Related

How to detect if SessionState has expired?

What would be the best way to detect if the SessionState has died in order to send the user to a "Session Expired" page? I've successfully configured the app (in Web.config) to do this when the authentication cookie is gone (there's a setting for that), but so far I haven't found an effective way to do something similar when the SessionState is gone. The app in question holds some data in the Session, and should present the user with a "Session Expired - Please login again" page if any of them is gone.
So far, the only option I can think of doing it in each of the places I access Session, but this is obviously a less than optimal solution.
I remember a similar question. Actually, you don't have many opportunities.
I mean, you can't redirect a user to a page when server fires the SessionEnd event, that you can handle in Global.asax.
However, if you play with the Session object from inside the page you can do something useful... For example, save the session ID in the page's context, or in a hidden field. When you postback, compare the saved ID with your Session ID. If they differ, a new session started, meaning that the old one expired.
Now it's time to redirect the user :)
Hope to have been of help.
Yeah it's tough. :)
There is no real simple/definitive way to do it.
One option is stick a guid/idenfitier in the Session[] collection during Session_Start (global.asax), and then check for this value in Page_Load of your base page (e.g master).
Another option is to check the actual ASPX cookie:
HttpCookie sessionCookie = Request.Cookies["ASP.NET_SessionId"];
If it's null, the session is over.
Why not include the session check on the masterpage? Any of your session variables will return null if the session has expired. So on page_load you can check any of them and carry out the appropriate action i.e. Response.Redirect. However you say in the Web.Config you can check when the authentication cookie is gone, so can you not carry out an action on this?
Another method would be to use a HTTP Module which would intercept each request and decide what to do with it. This would be better than my first method and it'll occur prior to any page processing.
When the client logs in, you give him a session flag, like notexpired and set it to 1.
Then you write a web-module, which on every http request checks if notexired = 1.
If that check throws an exception or is 0, you can deny access or redirect to an error page.
or you can renew the session from the database, should you save sessions into the database.
Incidentially, this also works with AJAX handlers, unlike base-page class hacks.
there are lots of examples on internet to solve your problem (it's quite common)
have a look at
http://geekswithblogs.net/shahed/archive/2007/09/05/115173.aspx
Another way is check the repository sessions values are maintained.
In my case we have a hashtable and we log the session ID then every time we need that session we checked if the value is still there..
That a centralized way to keep your app about the status of your session
Hope this helps/
Check out for this property at the Page_Load event of your desired page:
Dim sessionExpired as Boolean = Context.Session.IsNewSession
For more information, please visit this link.
Notice the "liveliness" of the session state is set by default to 20 min, but this can be easily changed in the web.config of the application with the timeout property:
<system.web>
<!--Set default timeout for session variables (default is 20 minutes, but was changed to 30 minutes-->
<sessionState mode="InProc" cookieless="false" timeout="30" />
</system.web>
Also, please check out at MSDN for the other properties mode and cookieles. It can help to extend the validity of your current business situation.

Authentication/Session cookie deleting after browser close

What are the exact steps required for a cookie to persist after a browser is closed? At the moment I have:
createPersistentCookie set to true on LoggedIn event.
MachineKey specified.
Forms sliding expiration set to true.
As long as the browser is open, the user will stay logged in, but as soon as it's closed, and it doesn't matter for how long, the user will need to log in again. What am I missing?
EDIT:
I went through the article pointed out by marapet (see comments below) and it made me interested in whether the ticket does indeed have IsPersistent flag, which it does. The decrypted ticket looks like this:
System.Web.Security.FormsAuthentication.Decrypt(Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName].Value)
{System.Web.Security.FormsAuthenticationTicket}
CookiePath: "/"
Expiration: {19/08/2010 17:27:14}
Expired: false
IsPersistent: true
IssueDate: {19/07/2010 17:27:14}
Name: "alex"
UserData: ""
Version: 2
All the details are correct, and correspond to those I set in LoggedIn event. More over the cookie value I can retrieve from the cookie directly, is identical to this one. Yet as soon as I close the browser, the cookie is lost.
What I have noticed, however, is that the cookie carrying the ticket has it's date reset for some reason. Firstly I can't override settings in web.config, so at the end of LoggedIn event it's Expires property is 4000 minutes after issue date, not a month which I am setting programmatically. Then after page load the cookie I retrieve with FormsAuthentication.FormsCookieName has Expires property of 01/01/0001. I think perhaps this is where the problem lies? Any thoughts would be appreciated.
EDIT#2:
I am changing both title and tags to include session, as it turned out to be relevant for the problem/solution
So I found the solution, eventually. As it turns out, it wasn't the problem with the authentication cookie as such (it was retained correctly, or rather would have been if the handler didn't remove it, having incorrectly decided that a user wasn't logged in based on the missing session). The problem was that the Session cookie was lost, or wasn't identified properly. So the fix was to manually add a session cookie during log on like so:
HttpCookie authCookie = new HttpCookie("ASP.NET_SessionId", Session.SessionID);
authCookie.Domain = ".mydomain.com";
authCookie.Expires = DateTime.Now.AddMonths(1);
Response.Cookies.Add(authCookie);
Now when the browsers opens again the session is identified properly and user session restored.
A persistent forms authentication cookie should not be discarded when the browser closes. It stays valid for the timeout value defined in the web.config.
However, some browsers can be configured to discard all cookies at the end of a session - you may want to check the settings of your browser (FireFox: Tools - options - privacy).

Session Fixation in ASP.NET

I'm wondering how to prevent Session fixation attacks in ASP.NET (see http://en.wikipedia.org/wiki/Session_fixation)
My approach would to this would normally be to generate and issue a new session id whenever someone logs in. But is this level of control possible in ASP.NET land?
Have been doing more digging on this. The best way to prevent session fixation attacks in any web application is to issue a new session identifier when a user logs in.
In ASP.NET Session.Abandon() is not sufficient for this task. Microsoft state in http://support.microsoft.com/kb/899918 that: ""When you abandon a session, the session ID cookie is not removed from the browser of the user. Therefore, as soon as the session has been abandoned, any new requests to the same application will use the same session ID but will have a new session state instance.""
A bug fix has been requested for this at https://connect.microsoft.com/feedback/viewfeedback.aspx?FeedbackID=143361&wa=wsignin1.0&siteid=210#details
There is a workaround to ensure new session ids' are generated detailed at http://support.microsoft.com/kb/899918 this involves calling Session.Abandon and then clearing the session id cookie.
Would be better if ASP.NET didn't rely on developers to do this.
Basically just do this in your Login GET method and your Logout method:
Session.Clear();
Session.Abandon();
Session.RemoveAll();
if (Request.Cookies["ASP.NET_SessionId"] != null)
{
Response.Cookies["ASP.NET_SessionId"].Value = string.Empty;
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-20);
}
If I am assuming right, you are talking about... http://en.wikipedia.org/wiki/Session_fixation. The short answer is yes, you have a lot of ways in which you can secure your cookie as well. You shouldn't be using cookieless session, and while you are using sessions, ensure that you have secured the cookie as well explicitly.
Check this article out... http://blogs.msdn.com/rahulso/archive/2007/06/19/cookies-case-study-with-ssl-and-frames-classic-asp.aspx
It does generate a new session ID when the user logs in, and kills a session when the timeout occurs, or the user navigates away/close the browser. And you can programmably kill it via Abandon() or remove entries via Remove().
So I'm not sure what the issue is?

After a few window.open calls my ASP.NET session times out

I have an ASP.NET application that uses StateServer session mode with cookieless set to false. In a few places, there is a link that pops up a window to another application (which happens to reside on the same domain, but in a different virtual directory). The following steps give me grief...
Launch popup
Close popup
Launch popup to same app as before with a couple different parameters
Close popup
Next request = session timeout on the "parent" window.
Using cookieless sessions fixes the problem, so somehow my cookie is getting whiped out by the browser. Aside from using cookieless sessions, how can this be resolved? For what it's worth, I am developing/testing with IE8.
EDIT
It seems the problem only occurs when the popup resides on the same domain. If I popup a page elsewhere, there is no problem.
Is it possible the other app (on the same domain) is setting its own cookie, overwriting that of your primary app? Can you use fiddler (or similar tool) to see which cookies are being set by which apps?
Check all instances of your
Session.Clear();
Session.Abandon();
If you aren't using those at all, then its likely the case that your browser windows are set to NOT share sessions between. So the new instance gets a NEW session cookie (since its the same cookie name as the prior one, it could possibly kill the existing session cookie)- as in a play on:
http://geekswithblogs.net/ranganh/archive/2009/04/17/asp.net-session-state-shared-between-ie-tabs-and-ie8.aspx
Ideally track down in which page the Set-Cookie header is coming across. Look then at the request going INTO that response and see if your current ASP.NET_SESSIONID cookie is sent over. (fiddler is indeed the best tool for this)
Anyway - its a start to try.
edit Apparently it's not your cookie name, so...
Perhaps you should have an AJAX call on your master page that pings a service (or generic handler) on your web app to keep the session alive.
JavaScript
window.setInterval(function() {
$.get('ping.ashx?nocache=' + (new Date()).getTime(), function() {
return true;
})
}, 30000);
In the Generic Handler, make sure to add the IRequiresSessionState marker interface.
Perhaps your session cookie names are the same.
In your web.config (for one of the applications) change the session cookie name.
<sessionState
mode="StateServer"
timeout="20"
cookieName="DifferentASP.NET_SessionId"

How to detect session timeouts when using cookieless sessions

I'm currently working on a ASP.Net 3.5 project and trying to implement session timeout detection. I know how to do it with enabled session cookies, but without i'm totally lost.
When session timeout occurs i want to redirect the user to some custom page.
Can someone explain me how to do it?
My cookie based solution looks like this and i wan't to reproduce its behaviour:
if (Session.IsNewSession && (Request.Cookies["ASP.NET_SessionId"] != null))
Response.Redirect("...");
Session_End in the global.asax should always be fired, despite the type of session used.
-edit: you might also be interested in
Session.IsNewSession
as this gives you information on new requests whether the previous session could have been timed out.
It looks like i've found a solution. I'm not very happy with it, but for the moment it works.
I've added a hidden field to my page markup
<asp:HiddenField ID="sessionID" runat="server" />
and following code to my CodeBehind
public void Page_Load(object sender, EventArgs eventArgs)
{
if (Context.Session != null) {
if (Context.Session.IsNewSession) {
if (!string.IsNullOrEmpty(sessionID.Value)) {
Response.Redirect("~/Timeout.aspx")
}
}
sessionID.Value = Context.Session.SessionID;
}
}
You also need to add this to your Web.config or ASP ignores all posted form fields
<sessionState cookieless="true" regenerateExpiredSessionId="false"/>
regenerateExpiredSessionId is the important attribute.
It pretty much works the same way - the session service updates a timestamp every time ASP.NET receives a request with that session ID in the URL. When the current time is > n over the timestamp, the session expires.
If you put something in session and check to see if it's there on each request, if it is not, you know the session is fresh (replacing an expired one or a new user).
I'd take a look at the "Database" section of AnthonyWJones' answer to a similar question here:
ASP.Net Session Timeout detection: Is Session.IsNewSession and SessionCookie detection the best way to do this?
In your session start event, you should be able to check a database for the existence of the SessionID - I assume that if I request a page with the SessionID in the URL, then that is the SessionID that I'll use - I've not tested that.
You should make sure you clear this DB down when a user logs out manually to ensure that you store a new instance of your flag.
If you don't like Session_End, you can try a very quick and dirty solution. Set up a Session["Foo"] value in Session_Start in global.asax, then check for Session["Foo"] in your page. If is null, the session is expired..
This is one of the solutions proposed in the Nikhil's Blog. Check it.

Resources