I am in Session_End() of Global.asax.cs
There is an operation I need to do only if the session was ended on a specific page. The parameters (sender and eventArgs) are not of any help. Is there a way to figure out last page the user was on?
Thanks in advance.
You can probably use HttpContext.Request property but not sure whether that will still be valid after session expire.
In such case, you need to explicitly write the page URL in cookies every time user request a new page. That way, even though session expires you can check the cookie object and see what was the last requested page.
General scenario, once session expires end user should be re-authenticating himself and thus you should redirect to login page directly and if you are using Forms Authentication then you can just say FormsAuthentication.RedirectToLoginPage();
You can store the URL of the last page accessed in Session with each request. That way when the session ends (global.asax Session_End) you can read what page the user had last visited before the session ended.
That's because most events are triggered by a request, but unless it's explicitly abandoned the session end is caused by a lack of activity. It's determined by the server when there hasn't been a request for a period. By definition there won't be any communication coming from the user indicating that the session is ending. They may have closed their browser five minutes ago.
(That's only if the session-state HttpSessionState.Mode property value is InProc. Otherwise the event won't fire.)
Related
I want to set 'Response.Cookies[ASP.NET_SessionId].Secure = true'. I was trying to do it in master page so that on every page load 'ASP.NET_SessionId' will be marked as secure. However, when i write this code, my HttpContext.Current.Session is all erased.
Can someone help how this works and what can be the solution
How Session cookie gets created ?
ASP.NET fires the session_start event on very first request and creates an "ASP.NET_SessionId" cookie on client browser.
Session getting erased ?
Can you check if your browser is sending the same session cookie value as originally created on first request? Ideally, asp.net identifies and track user's session based on the cookie value.
Share relevant code if that permits you.
Thanks
I have an asp.net web form. when a user authenticate, it create a Secured cookie called .aspxauth
uppon logout, I call these 2 methods
FormsAuthentication.SignOut();
Session.Abandon()
Problem is that we had penetration test and if I steal the cookie, logout and manually reinsert the cookie, I become loggued in again. So the .aspauth isn't invalidated server side.
I've googled it and I can't find the answer to that security breach.
Microsoft has acknowledged this issue here: https://support.microsoft.com/en-us/kb/900111
They offer several ideas for mitigating this vulnerability:
protect the application by using SSL
Enforce TTL and absolute expiration
Use HttpOnly cookies and forms authentication in ASP.NET 2.0
Use the Membership class in ASP.NET 2.0
Regarding the last one, I'll paste the contents from the site for convenience/preservation:
When you implement forms authentication in ASP.NET 2.0, you have the option of storing user information in a Membership provider. This option is a new feature that is introduced in ASP.NET 2.0. The MembershipUser object contains specific users.
If the user is logged in, you can store this information in the Comment property of the MembershipUser object. If you use this property, you can develop a mechanism to reduce cookie replay issues in ASP.NET 2.0. This mechanism would follow these steps:
You create an HttpModule that hooks the PostAuthenticateRequest event.
If a FormsIdentity object is in the HttpContext.User property, the FormsAuthenticationModule class recognizes the forms authentication ticket as valid.
Then, the custom HttpModule class obtains a reference to the MembershipUser instance that is associated with the authenticated user.
You examine the Comment property to determine whether the user is currently logged in.
Important: You must store information in the Comment property that indicates when the user explicitly signed out. Also, you must clear the information that is in the Comment property when the customer eventually signs in again.
If the user is not currently logged in as indicated by the Comment property, you must take the following actions:
Clear the cookie.
Set the Response.Status property to 401.
Make a call to the Response.End method that will implicitly redirect the request to the logon page.
By using this method, the forms authentication cookie will only be accepted if the user has not been explicitly signed out and the forms authentication ticket has not yet expired.
Read this article about Session fixation and how to get rid of it once and for all:
http://www.dotnetfunda.com/articles/show/1395/how-to-avoid-the-session-fixation-vulnerability-in-aspnet
This remains an issue in .NET Framework. Everyone seems to think Session.Abandon() is the answer, but the sad truth is that command does not invalidate the session on the server's side. Anyone with the right token value can still resurrect a dead session, until the session expires based on the Web.config settings (default = 20minutes).
A similar questioner posed this question a long time ago here:
Session Fixation in ASP.NET
Most of those links are dead, and Microsoft has no new news on the topic.
https://forums.asp.net/t/2154458.aspx?Preventing+Cookie+Replay+Attacks+MS+support+article+is+now+a+dead+link
Worse still, you're still vulnerable to this cookie replay attack even if you're implementing a completely stateless MVC application and don't use the Session object to store data between views. You can even turn off session state in the web.config settings and still replay cookies to gain access to a logged-out session.
The true solution is hack-y and described here, and you need to have session data enabled InProc to use it.
When the user logs in, set a boolean value in the session data, like Session["LoggedIn"] = true;, which is stored on the server side.
When the user logs out, set that value to false.
Check the session value on every request--an attacker trying to replay a session isn't going to be nice to you and come in through the Login page only. It's probably easiest to do this using a custom filter and registering it globally in the global.asax file (so you don't have to duplicate the code everywhere, or attribute every controller/method).
Even if the attacker has all the cookie values, they won't be able to re-use that same session ID, and the server will automatically delete it once it reaches the specified timeout.
if you are using the FormsAuthentication, you can use this code. By using this code you can destroy the created cookies by setting the Expire property of HttpCookie. It will help you:
FormsAuthentication.SignOut();
Session.Clear();
Session.Abandon();
Session.RemoveAll();
// clear authentication cookie
HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
httpCookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(httpCookie);
I am very confused in my implementation of sessions in asp.net web application. My logic is once user enters user name+password, I validate credentials and then create a new session with some user info[All I am after from this point onward is that this user has access to restricted resources and a user must never be able to access those resources unless he/she is authenticated]. This I validate on each request and the rest. Here is my issue though. I have many places in the website where I have html links, and I read that if I have a link such as
<a href='resource1.aspx'>resource 1</a>
This will generate a new session id, hence in reality invalidating the existing session id, which in my case will be treated as session expired and user is sent to login page. While reading up on this issue I came across an asp.net API method[
Response.ApplyAppPathModifier(url);
] which prepends the session id to each request hence resolving the new session id generation for each link. Though it resolves session breaking issue it does add the session id next to all of the urls and now session id can be seen in the source code( view source for web page). I really don't want to use cookies and want to use session for user sessions...Can some one please help me create a system which will work the way I wish it to ? if I am doing it utterly incorrect, I would really really appreciate a details discussion and if possible some example...Thanks you much in advance..
It looks like you are trying to use cookieless sessions which add a session id to all links in order to be able to track the sessions.
The other (much more common, standard and IMO secure) approach is to use normal sessions, which auto creates a session cookie (when you use the .Session object), and uses that to determin the current session. If you don't want a cookie you'll have to stick with cookieless, and the session id in the url.
I need to show user log in time details.I have two table.One is UserMaster which contains UserDetails and one is UserLogInTimeDetails contains two columns UserId and LogedInTime.
When User Log in UserId and LogInTime stores in UserLogInTimeDetails.
When User Log Off I am deleting the row of that particular user from UserLogInTimeDetails.
But the problem is if an user close the browser then the details of the user in not deleted from UserLogInTimeDetails table.For which that user will not be able to log in again.
How to solve this issue?
I have googled and saw that browser close event in not possible to handle and in many places they have adviced to use onbeforeunload event which is not working for me.
Please help. I am in big trouble.
Perhaps you could get it working using Session_End in your global.asax file to remove the user when their session expires. Though I'm not 100% sure if you can get the session ID from this method. It may be within the EventArgs...
void Session_End(Object sender, EventArgs e) {
//Remove user from database here
}
Else, another way to store the data is based on last activity, so everytime the user submits a request you update the time of last activity. You could even store this with a session ID in the database along with their login time, and then be able to calculate the duration active from login time to last activity for that session;
Best way to go with this using signalR. You can track user is online or offline. based on even dispose you can track exact logout or browser close too.
Hope this will teach you something new. refer below link for a simple example of signalR.
signalR sample application for online, offline status
Is it important that the user cannot login multiple times from different browsers?
If not, a more common approach is to store a login information variable in a session variable (maybe login time, user id or something like that), and use it to verify if the user has logged in or not.
If the user close the browser the session is lost, and he must login again, but he can login as many times as he wishes from different browsers.
You can access these variables like this:
// Set it like this. Can be any type of object with login data.
Session["LoginData"] = "Hello";
// Get it like this.
string test = (string)Session["LoginData"];
Edit:
If it is important that the user must nog login multiple times, you have a much bigger problem to solve.
Maybe something like this could be the solution?
Let the browser (via ajax) ping the web server somehow, every few seconds or so (how many depends on how long you want the browser to be shut down before it is ok to login again vs. traffic)
When the server receives a ping from a certain user, stamp the date and time in a session variable.
If a browser is trying to access the web page in any way, first, check for the session and for how long time ago the last ping was done. If the session is null, or the time is more than the time between pings*2 (or something like that) the user can login again (send to login page). If the time is shorter check if the user is logged in. If he is, continue. If not, tell him he must log out from the first connection (or whatever you want).
Hope this helps!
We have a page of search results which the user can hit in several ways. 90% of the ways will set up a 'Search Criteria' session object, which the results page will use to retrieve the search results.
When the session object isn't found, we will typically show the user an 'invalid search' message, and give them a link to the main search page.
The exception is the case where the user hits a webpage which has the search results page as it's default page (we use .NET's themes to provide private labels for our site, skinning it with our affiliates' colors and logos). If the search results page is the default page for the site, there is a special search that is preformed when there is no session criteria.
This is working fairly well in our testing, but there is an edge case we would like to handle: When a session expires while someone is on the search results page (having come from the search page) and they then click on the next page of results, they will get this special search instead of the 'expired session' message.
This is the basic format we're using, where searchCriteria is set from session.
if (searchCriteria == null)
{
if (/*Check if this is the default url for this site*/)
{
//Preform special search
}
else
{
//Display 'session expired message'
}
}
Is there a way we can check Session in the inner if block to see if the user's session is new due to expiration of an existing? Or do browsers just throw away the session cookies when they expire?
Is there a browser difference? Do some return the expired session cookie to the server, while other's delete them on expiration? Or is it consistent?
This is an excellent article which is based off of this one. I think you will find your answers here (Page 2 of the second article specifically)
All the browsers will return the expired session cookie. They'll do so until the browser is restarted or it's rewritten by a server response.
The answer from bnkdev uses this fact to detect new vs expired by seeing if the cookie is already set. It's simple and easy and will likely work for you, but it only works when cookies are used for session ids. It won't work for cookieless sessions.
Also, rather than hard coding "ASP.NET_SessionId", you should probably fetch it from the cookieName attribute of the sessionState configuration element.