ASP.NET Session and Authentication tokens are not tightly bound to user sessions, and ASP.NET will accept any token the client provides.
We can learn how to use the Built-in state management features combined with client-side cookies to provide an extra layer of security
Additional security is provided by:
- Token Creation
- Session Creation & Session Termination
Token creation
Session management token should be a Random number generated (Strong Algorithm) and should not directly identify a user.
Random numbers are an important aspect of security, but they must have certain properties to be considered truly random. For instance, the number should not be predictable or reproducible, and it should be large enough to prevent someone guessing it. When ASP.NET creates a session token, it uses a strong random-number generator to create a 120-bit key, which is certainly adequate for most purposes. This session token is stored in a cookie named ASP.NET_SessionId or on the URL if you're using a cookieless state. This session token is also available through the SessionID property of the Session object.
Check the code Sample in C# mentioned below…
private void enhanceSessionIdWithMac()
{
string SessionMacCookieValue;
// Check if there is a SessionMac cookie
if (Request.Cookies["SessionMac"] == null)
{
SessionMacCookieValue = null;
}
else
{
SessionMacCookieValue = Request.Cookies["SessionMac"].Value;
}
// Create and store hash
if (Session["key"] == null && SessionMacCookieValue == null)
{
Session["key"] = CreateKey();
string hash = createHMASCHA1(Encoding.Unicode.GetBytes(
Session.SessionID),
Encoding.Unicode.GetBytes(
(string)Session["key"]));
HttpCookie SessionMac = new HttpCookie("SessionMac", hash);
Response.Cookies.Add(SessionMac);
}
// Check against stored hash
else
{
string createdHash = createHMASCHA1(
Encoding.Unicode.GetBytes(
Session.SessionID),
Encoding.Unicode.GetBytes(
(string)Session["key"]));
if (createdHash != Request.Cookies["SessionMac"].Value)
{
Session.Abandon();
Response.Redirect("default.aspx");
}
}
}
Above code creates a MAC based on the Session Identifier using a Random Number stored on a server as the key. Based on the client request the MAC is computed and matched against with the cookie stored in the client side.
Session Creation
Below code sample explains how to obtain the client information and store it in the session state.
private void bindingToTheClient()
{
// get the first two octets
string[] userIpArray = Request.UserHostAddress.Split('.');
string firstTwoOctets = userIpArray[0] + "." + userIpArray[1];
if (Session["firstTwoOctets"] == null &&
Session["userAgent"] == null)
{
Session["firstTwoOctets"] = firstTwoOctets;
Session["userAgent"] = Request.UserAgent;
}
else
{
if ((string) Session["firstTwoOctets"] != firstTwoOctets ||
(string) Session["userAgent"] != Request.UserAgent)
{
Session.Abandon();
Response.Redirect("default.aspx");
}
}
}
Session Termination
Since ASP.NET automatically handles idle session timeouts, we can use session state to store the other two variables. Below code sample show how to use, store, and check the absolute expiration and hit counter.
private void expiringSessions()
{
if (Session["absoluteExpiration"] == null &&
Session["maxHitCount"] == null)
{
Session["absoluteExpiration"] =
DateTime.Now.AddHours(2); // Two hours from now
Session["maxHitCount"] = 3; // Fifty hits to the website
Session["hitCount"] = 0;
}
else
{
Session["hitCount"] = (int) Session["hitCount"] + 1;
// Check if session has expired, or exceeded max hit count
if (DateTime.Now > (DateTime) Session["absoluteExpiration"] ||
(int) Session["hitCount"] > (int) Session["maxHitCount"])
{
Session.Abandon();
Response.Redirect("default.aspx");
}
}
}
Happy Learning !!