How to avoid the Session fixation vulnerability in ASP.NET?

Itfunda
Posted by in ASP.NET category on for Intermediate level | Points: 250 | Views : 48671 red flag
Rating: 5 out of 5  
 2 vote(s)

In this article, we are going to learn how to avoid the Session fixation vulnerability in ASP.NET.

Introduction


ASP.NET Session keeps track of the user by creating a cookie called “ASP.NET_SessionId” in the user browser. This cookie value is checked for every request to ensure that the data being served is specific to that user. In many application, Session variable is used to track the logged in user, ie. If a session variable exists for that user then the User is logged in otherwise not.

The vulnerability


Whenever any data is saved into the Session, “ASP.NET_SessionId” cookie is created in the user’s browser. Even if the user has logged out (means the Session data has been removed by calling Session.Abandon() or Session.RemoveAll() or Session.Clear() method),  this “ASP.NET_SessionId” cookie and its value is not deleted from the user browser. This legitimate cookie value can be used by hijacker to hijack the user session by giving a link that exploits Cross Site scripting vulnerability to set this pre-defined cookie. When the user clicks this link and logs in, user will have the same “ASP.NET_SessionId” cookie value that hijackers knows and he will be also able to browser user account and will be able to access all information pertaining to that user. This attack is called Session fixation vulnerability.

Get hundreds of solutions like this in our .NET How to video tutorials.

Let’s create a demo application that shows the existence of “ASP.NET_SessionId” cookie even if the user has logged out and all Session data has been removed.

ASPX PAGE

<fieldset>

<legend>Login</legend>

<p>

Username :

<asp:TextBox ID="txtU" runat="server" />

</p>

<p>

Password :

<asp:TextBox ID="txtP" runat="server" />

</p>

<p>

<asp:Button ID="btnSubmit" runat="server" Text="Login" OnClick="LoginMe" />

<asp:Label ID="lblMessage" runat="server" EnableViewState="false" />

<asp:Button ID="btnLogout" runat="server" Text="Logout" OnClick="LogoutMe" Visible="false" />

</p>

</fieldset>

In the above code snippet, we have two TextBoxes, two Buttons and a Label control. 

CODE BEHIND

protected void Page_Load(object sender, EventArgs e)

{

if (Session["LoggedIn"] != null)

{

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();

}

else

{

lblMessage.Text = "Wrong username or password";

}

}

protected void LogoutMe(object sender, EventArgs e)

{

Session.Clear();

Session.Abandon();

Session.RemoveAll();

}

On click of the Login button, LoginMe method fires that creates Session[“LoggedIn”]  after validating the TextBoxes value. 

On click of the Logout button, we are calling Session.Clear(), Session.Abandon() and Session.RemoveAll() methods to ensure that the session variable is removed.

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.


Page copy protected against web site content infringement by Copyscape

About the Author

Itfunda
Full Name: IT Funda
Member Level: Starter
Member Status: Member
Member Since: 5/21/2011 3:32:40 AM
Country: India
Thanks Regards
http://www.itfunda.com/
Get .NET How to | jQuery How to.

Login to vote for this post.

Comments or Responses

Posted by: Karthikanbarasan on: 6/7/2011 | Points: 25
Nice topic!!!
Posted by: Millibel on: 12/18/2012 | Points: 25
I have tried to implement this in my exercise project how ever, in case of fixation ( if (!Session["AuthToken"].ToString().Equals (Request.Cookies["AuthToken"].Value)), I ran into infinite loop where the master page redirect to login page and again master page page_load method executes before login page shows. i.e since the session and the cookie value is not equal, it is infinite loop. Did i missed some thing?
nice topic tho.

Login to post response

Comment using Facebook(Author doesn't get notification)