We have two factor authentication in place to login into our system.
User has to login using username/password.
In the next page, user has to answer security questions to successfully login into our application.
We are creating multiple sessions upon user successfully authenticated in step #1. This session information will be used across the application.
I have used below peace of code to handle session fixation issue:
When user browse the application login page, I am deleting the sessionid in the session-cookie using below code in the page load.
if(!IsPostBack)
{
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
HttpContext.Current.Session.RemoveAll();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
}
The above code will empty the sessionid in the session cookie. Now when user enter the appropriate credentials asp.net will create new session id automatically, so browser will get new session upon successful authentication. If user entered wrong credentials then using above code i am resetting the sessionid again so the new sessionid will automatically generated up on successful authentication.
This approach worked fine for single factor authentication and session fixation was no more a defect in security reports. But with multi factor authentication still it is an issue. I couldn't use above code to reset the cookie sessioid in the page where i am verifying the security answers as the application loosing all the session variables created in step #1.
As a work around in #2, after answering security questions successfully I have tried to save session values in the temporary object and reset the sessioid in the cookie and reassigning the object to session variables again, but sessionid is not regenerating at this point of time so i coudln't re save the session and application started throwing the exceptions wherever those session variables being accessed.
Below is the event triggered up on successful authentication in step #2 page
private void Sucess()
{
login = Session.logininfo
HttpContext.Current.Session.Abandon();
HttpContext.Current.Session.RemoveAll();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
Session.logininfo = login;
Response.Redirect("New.aspx", true);
}
May i know is there any better way to update the session cookies in this case.
Related
I have been banging my head against the wall and searching the web for this but I think I am having issues understanding the whole process of logging users out of an asp.net webforms application. The issue:
I am able to log in to my application and it uses cookies, so I have my cookie set in the browser.
here is the config forms authentication section,
<forms loginUrl="login.aspx" timeout="15" protection="All" name="Domain.MYDOMAIN" path="/" domain="mysite.local" cookieless="UseDeviceProfile"/>
here is the front end control
<li><asp:LoginStatus ID="LoginStatus1" runat="server" OnLoggedOut="OnLoggedOut" /></li>
In the OnLoggedOut Method we do something like this.
protected void OnLoggedOut(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
/* Abandon session object to destroy all session variables */
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
Response.Redirect("~/login.aspx");
}
This will clear the cookies from the browser. But if before I do this I copy the cookie name pair value of Domain.MYDOMAIN = "what ever it would be"
and add that to a postman call, it is still showing me as logged in! Very frustrating.
when I am logged in
I log out using the logout button mentioned above and the cookie is removed
Then I take that cookie to Postman and make the call to the landing / default page and it is showing me as logged in still!!!
I have been reading that the cookie is related to a "ticket" but I am not sure how to expire that ticket on the server side. Once the user clicks logout I dont want this cookie value to be used again to reach a page, any page within the application. Any help would be appreciated! Thank You!
Side Note: I have my session state set to InProc
<sessionState mode="InProc" />
Ones the user is authenticate with user name and password, then we set a cookie that have a time out and this cookie let him login.
Even if you delete the cookie from one browser, if you still have it and place it again – you permit to login again because the cookie is gives the “OK” to do that.
This is not only on asp.net but everywhere (Microsoft, google, Facebook).
To add an extra layer of security, and avoid to someone steal the cookie:
First step is to force only the SSL for the cookies (*). <httpCookies httpOnlyCookies="true" requireSSL="true" />. Using that you make it difficult to impossible to steal the cookie
Second step is on logout to save that cookie on a database, then on every request check if the cookies have been logged out
Third step is to also check if the cookie come from the same browser id.
So, you connect the cookie with the browser data, and with a flag that the user press the logout.
You make that checks on global.asax
protected void Application_BeginRequest(Object sender, EventArgs e)
(*) The first step : Can some hacker steal a web browser cookie from a user and login with that name on a web site?
The difficult way is to add the database extra layer of protection and connect the cookie with other user information's as I say, the browser id, and a flag if have been logged out. The main idea is to keep on server the authenticated cookie that you have set and double check it - now you don't do that.
I'm using the standard Authentication middleware in my Startup.cs file like this:
services.AddAuthentication("auth")
.AddCookie("auth", options =>
{
options.LoginPath = new PathString("/account/index");
options.AccessDeniedPath = new PathString("/account/forbidden");
options.SlidingExpiration = true;
});
I want to be able to display a "Your session has expired" message on my login page once the user is redirected there because of an expired session. And obviously not have it there when a new user is visiting the page.
By the looks of it, the Authentication middleware simply checks for a 401 passed from another middleware and changes it to a 302 to my desired location, leaving me no chance of differentiating between those two.
Can I achieve this differentiation by using the standard .net core 2.0 libraries, or should I go for a custom implementation instead?
If you want to detect whether or not the user was logged in, you could set a second unrelated Session cookie saying that the user HAD a session. Do not store any other information in the cookie. Let's call this a 'Flag' cookie.
When the user logs in, you create both a session cookie and a flag cookie. The session cookie can expire whenever you set it to, and the flag cookie should never expire. Lets say after 30 days, you are automatically logged out of your account - the session cookie should expire. Because you still have the flag cookie but not the session cookie, you can check on each page if you have the flag cookie when no session cookie is present.
If the Flag cookie exists but the actual session cookie does not, you can redirect to the login page and inform them that their login session has expired. I'd be sure to delete the cookie once you get there too so that every time they load a page they aren't redirected to login. This means the message will only show once to the user so they can still try visiting other pages on the site afterwards without being redirected should they want to browse (for example the homepage) but not want to log back in. If they attempt to access an authenticated page, they should be prompted for credentials again
Please read my following statements and tell me if they are true or false for persistent cookies:
Session and cookie are created when user logs in.
Session is created with a unique id which is stored in the cookie.
By default, a cookie stores session id only. If a developer wants, then he can store other information in that cookie with session id.
Session variables, if any, are removed from server memory after the session is expired or user logs out but the session id is still in the cookie.
If its true, then what is the use of session id ?
After this, user would again logs in and the cookie is replaced with a new session id. Right ?
After the cookie is expired, the session id is removed from cookie and the cookie is deleted.
For security purpose, the session must be expired before cookie. In this way, user is forced to authenticate himself and logs in to confirm its identity again.
What's the purpose of the cookie? The server has to be able to recognize which session belongs to which client. So the SessionID is provided to the client, and communicated back and forth via cookie (or via QueryString if cookieless authentication is enabled, but that isn't recommended).
User logging in or out doesn't necessarily change the SessionID. To do that, you'd need to call Session.Abandon().
I am having problem in session management in my asp.net. I am logging out of the admin and user account, but as i am pressing the forward button of the browser, the page is redirected again to the User/Admin account. I already destroyed the session i created for storing the username, everytime i am clicking the log out button.
In every page you have you should implement a small if sentence in the Page_Load that checks if the Session is null like so:
if(Session["User"] == null)
Response.Redirect("~/Login.aspx");
Make sure that when you log out, you make sure that the Session is set to null.
If you are using the default template of Visual Studio this may help you:
if(!HttpContext.Current.User.Identity.IsAuthenticated)
{
Response.Redirect("~/Login.aspx");
}
There might be two problems here:
First Problem (Server Side):
Using Session to store authentication and authorization is a poor way to design the application. Use the ASP.NET Authorization and Authentication(FormsAuthentication) framework to do this. This way, your application can use client side cookies to store authentication information, and can allow only certain users to access certain pages in your application(using Authorization).
Session data is lost each time the ASP.NET recycles the application pool(which might happen at random). This is potentially dangerous and can cause NullReferenceExceptions during usage.(This happens if Session management is inproc which is the default)
Second Problem (Client Side):
Usually, the browser caches the page, so the Page_Load will not be executed on the server side. To work around the problem, you can add this code in Page_Load event on each page if you want to(or add it to a Master Page) :
Response.Buffer=true;
Response.ExpiresAbsolute=DateTime.Now.AddDays(-1d);
Response.Expires =-1500;
Response.CacheControl = "no-cache";
And, then, the Authorization|Authentication part of ASP.NET will gracefully redirect you to Login.aspx page, if, the user has been logged out.
Using some more code, you can even redirect to the homepage for a particular user, if the user is already authenticated based on a certain roleID.
Here's the situation:
User1 logs in with IE to the web site. Once they pass authentication they go to the default page (page1). On page one, user makes a selection which results in a querystring with parameters, and goes to page 2 as specified in the querystring.
User2 logs in with Chrome (I want to be sure they have a different session). Once they pass authentication they go to page 2 and the querystring is the same as the first user's querystring. Same parameters, and they've bypassed page1!
Looks to me like the querystring is being stored at the application level.. but I thought user sessions should always be truly isolated from each other. I have the same problem with session variables- crossover between users.
Is there a way to guarantee unique sessions as users log in? Any other suggestions? Using C#.net
Thanks,
I overcame this by pulling an all nighter and experimenting with IIS7 configuration. I defined a simple test which showed the error (login with IE, click a button, leave session up, launch safari, login). Then I went through every permutation of session state config and retested.
In the end, Session State Mode settings are now: In process, use cookies, name: ASP.NET_SessionID, timeout = 20, regenerate expired session ID = false, Use hosign identity for impersonation = true.
What can I say, it's working!
da