Output
ASP.NET_SessionId cookie when user is logged in
Notice in the below image that when user has logged in, an “ASP.NET_SessionId” cookie has been created.
(After clicking on Login, go back and refresh the page)
Now when we clicked on Logout button, even if the Session has been abandoned / removed, the “ASP.NET_SessionId” cookie exists.
ASP.NET_SessionId cookie even if user is logged out
(After clicking on Login, go back and refresh the page)
How to fix this vulnerability
Simple fix
To avoid Session fixation vulnerability attack, we can explicitly remove the “ASP.NET_SessionId” cookie in the Logout method.
Bullet proof fix
To bullet proof this attack, we can create another cookie (eg. AuthCookie) with a unique value and the same value can be stored into the Session as well. On every page load, we can match this cookie value with the Session value, if both matches then let the use enter into the application otherwise redirect to the Login page.
In the Logout function, ensure that you are removing this new Cookie “AuthCookie” as well. To remove this cookie, simply set its expiration date time to few months earlier than current date time.
So my modified code behind for this page looks like below
MODIFIED CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
//NOTE: Keep this Session and Auth Cookie check condition in your Master Page Page_Load event
if (Session["LoggedIn"] != null && Session["AuthToken"] != null && Request.Cookies["AuthToken"] != null)
{
if (!Session["AuthToken"].ToString().Equals(Request.Cookies["AuthToken"].Value))
{
// redirect to the login page in real application
lblMessage.Text = "You are not logged in.";
}
else
{
lblMessage.Text = "Congratulations !, you are logged in.";
lblMessage.ForeColor = System.Drawing.Color.Green;
btnLogout.Visible = true;
}
}
else
{
lblMessage.Text = "You are not logged in.";
lblMessage.ForeColor = System.Drawing.Color.Red;
}
}
protected void LoginMe(object sender, EventArgs e)
{
// Check for Username and password (hard coded for this demo)
if (txtU.Text.Trim().Equals("u") && txtP.Text.Trim().Equals("p"))
{
Session["LoggedIn"] = txtU.Text.Trim();
// createa a new GUID and save into the session
string guid = Guid.NewGuid().ToString();
Session["AuthToken"] = guid;
// now create a new cookie with this guid value
Response.Cookies.Add(new HttpCookie("AuthToken", guid));
}
else
{
lblMessage.Text = "Wrong username or password";
}
}
protected void LogoutMe(object sender, EventArgs e)
{
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 (Request.Cookies["AuthToken"] != null)
{
Response.Cookies["AuthToken"].Value = string.Empty;
Response.Cookies["AuthToken"].Expires = DateTime.Now.AddMonths(-20);
}
}
LoginMe method
First focus on the LoginMe method that fire on click of the Login button. In this method, after setting the normal Session variable, we are creating a GUID (a unique value and almost impossible to guess) and saving it as a new Session variable called “AuthToken”. The same GUID is being saved into a cookie named “AuthToken”.
LogoutMe method
In the LogoutMe method, we are first explicitly expiring the “ASP.NET_SessionId” cookie to make sure that this cookie is removed from the browser when user clicks on the Logout button and after that we are expiring the “AuthToken” cookie as well.
Page_Load event (In real time application, keep this logic into the Master Page Page_Load method)
In the Page_Load event we are checking for the normal “LoggedIn” session variable and along with that we are also checking for the new Session variable called “AuthToken” and new Cookie “AuthToken”, if all three of them are not null then again we are matching the new Session variable “AuthToken” and new Cookie “AuthToken” values, if both are NOT same, then we are writing failure message (in real time application, redirect the user to the Login page).
This logic makes sure that even if “ASP.NET_SessionId” cookie value is known to the hijacker, he will not be able to login to the application as we are checking for the new Session value with new cookie that is created by us and their GUID value is created by us. A hijacker can know the Cookie value but he can’t know the Session value that is stored into the web server level and as this AuthToken value is changing every time user is logging in so the older value will not work and hijacker will not be able to even guess this value. Unless the new Session (“AuthToken”) value and new Cookie (“AuthToken”) is same, no one will be able to login to the application.
OUTPUT
ASP.NET_SessionId along with AuthToken cookie
Hope you find this article interesting, thanks for reading. Subscribe to our RSS feed to read more articles on regular basis.