Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Session Fixation - Change sessionId on asp.net core 2

Based on what i have understood we have

  1. sessionId is stored in the cookie .AspNetCore.Session
  2. Deleting the cookies and Clearing the session does nothing.

    context.HttpContext.Session.Clear();
    foreach (var cookie in context.HttpContext.Request.Cookies.Keys)
    {
         context.HttpContext.Response.Cookies.Delete(cookie);
    }
    

So the question is can we change the sessionId somehow, or is there a way to protect us from Session-Fixing?

like image 961
Bill Togkas Avatar asked Oct 28 '22 23:10

Bill Togkas


1 Answers

...or is there a way to protect us from Session-Fixing?

Yes there is! OWASP states:

Unfortunately, some platforms, notably Microsoft ASP, do not generate new values for sessionid cookies, but rather just associate the existing value with a new session. This guarantees that almost all ASP apps will be vulnerable to session fixation, unless they have taken specific measures to protect against it.

The same page recommends an approach for ASP.Net, which we used for all of our ASP.Net applications and which passed pen testing. I think it is still valid for ASP.Net Core:

The idea is that, since ASP prohibits write access to the ASPSESSIONIDxxxxx cookie, and will not allow us to change it in any way, we have to use an additional cookie that we do have control over to detect any tampering. So, we set a cookie in the user’s browser to a random value, and set a session variable to the same value. If the session variable and the cookie value ever don’t match, then we have a potential fixation attack, and should invalidate the session, and force the user to log on again.

This is a simplified example of how we approached this in .Net Core Razor Pages and should give you an idea of how to implement it yourself:

public IActionResult OnPost()
{
    Login();

    return Redirect("~/Login");
}

private void Login()
{
    // Check the user's credentials and do all the other necessary stuff.
    // ... 

    // Create the random value we will use to secure the session.
    string authId = GenerateAuthId();

    // Store the value in both our Session and a Cookie.
    HttpContext.Session.SetString("AuthId", authId);
    CookieOptions options = new CookieOptions()
    {
        Path = "/",
        HttpOnly = true,
        Secure = true,
        SameSite = Strict
    };
    Response.Cookies.Append("AuthCookie", authId, options);
}

private string GenerateAuthId()
{
    using(RandomNumberGenerator rng = new RNGCryptoServiceProvider())
    {
        byte[] tokenData = new byte[32];
        rng.GetBytes(tokenData);
        return Convert.ToBase64String(tokenData);
    }
}

Check the content of the Session and Cookie wherever you need it. If they don't match, you should Clear the Session (I don't think Session.Abandon is still available in .Net Core) and log out the user.

public void OnGet()
{
    string cookieValue = Request.Cookies["AuthCookie"];
    string sessionValue = HttpContext.Session.GetString("AuthId");

    if (cookieValue == null || sessionValue == null || cookieValue != sessionValue )
    {
        // Invalidate the session and log out the current user.
    }
}
like image 134
display-name Avatar answered Nov 24 '22 23:11

display-name