Session Fixation - Change sessionId on asp.net core 2

Bil*_*kas 6 session asp.net-core

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);
    }
    
    Run Code Online (Sandbox Code Playgroud)

所以问题是我们可以以sessionId某种方式改变,或者有没有办法保护我们免受会话修复?

rm-*_*ode 5

\n

...或者有没有办法保护我们免受会话修复?

\n
\n\n

就在这里!OWASP指出:

\n\n
\n

遗憾的是,某些平台(特别是 Microsoft ASP)不会为 sessionid cookie 生成新值,而只是将现有值与新会话相关联。这保证了几乎所有 ASP 应用程序都容易受到会话固定的影响,除非它们采取了特定的措施来防止它。

\n
\n\n

同一页面推荐了一种用于 ASP.Net 的方法,我们将其用于所有 ASP.Net 应用程序并通过了笔测试。我认为它对于 ASP.Net Core 仍然有效:

\n\n
\n

这个想法是,由于 ASP 禁止对 ASPSESSIONIDxxxxx cookie 进行写访问,并且不允许我们以任何方式更改它,因此我们必须使用我们确实可以控制的附加 cookie 来检测任何篡改。因此,我们将 user\xe2\x80\x99s 浏览器中的 cookie 设置为随机值,并将会话变量设置为相同的值。如果会话变量和 cookie 值不匹配,那么我们就有潜在的固定攻击,应该使会话无效,并强制用户再次登录。

\n
\n\n

这是我们如何在 .Net Core Razor Pages 中实现这一点的简化示例,应该能让您了解如何自己实现它:

\n\n
public IActionResult OnPost()\n{\n    Login();\n\n    return Redirect("~/Login");\n}\n\nprivate void Login()\n{\n    // Check the user\'s credentials and do all the other necessary stuff.\n    // ... \n\n    // Create the random value we will use to secure the session.\n    string authId = GenerateAuthId();\n\n    // Store the value in both our Session and a Cookie.\n    HttpContext.Session.SetString("AuthId", authId);\n    CookieOptions options = new CookieOptions()\n    {\n        Path = "/",\n        HttpOnly = true,\n        Secure = true,\n        SameSite = Strict\n    };\n    Response.Cookies.Append("AuthCookie", authId, options);\n}\n\nprivate string GenerateAuthId()\n{\n    using(RandomNumberGenerator rng = new RNGCryptoServiceProvider())\n    {\n        byte[] tokenData = new byte[32];\n        rng.GetBytes(tokenData);\n        return Convert.ToBase64String(tokenData);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在需要的地方检查 Session 和 Cookie 的内容。如果它们不匹配,您应该Clear会话(我认为Session.Abandon在 .Net Core 中仍然不可用)并注销用户。

\n\n
public void OnGet()\n{\n    string cookieValue = Request.Cookies["AuthCookie"];\n    string sessionValue = HttpContext.Session.GetString("AuthId");\n\n    if (cookieValue == null || sessionValue == null || cookieValue != sessionValue )\n    {\n        // Invalidate the session and log out the current user.\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


Chr*_*att 0

Session.Clear只删除会话中的所有数据,实际上并没有删除会话本身。当超时时就会发生这种情况。在我看来,对于 ASP.NET Core 团队来说,没有Session.Abandon像以前那样实现是一个奇怪的选择,因为这实际上删除实际的会话本身。

只要实际的会话还存在,即使它的数据不再存在,仍然可以通过该会话id检索到它,这样问题就转移到了客户端。

重要的是,服务器实际上不能让客户端做任何事情。调用Cookies.Delete实际上只Set-Cookie为同一个 cookie 发送一个新的响应标头,并且过期日期已经过去。这应该会提示客户端(最有可能是浏览器)删除该 cookie,因为它现在已过期。然而,这完全 100% 取决于客户端,因此,如果存在错误或客户端没有接受更改,或者客户端出于某种原因拒绝遵守,则 cookie 将保留。然后,如果 cookie 仍然存在并且由它包含的会话 id 标识的会话仍然存在,则可以将其恢复。

总而言之,您拥有的代码应该可以工作,并且除了您已经在做的事情之外,您实际上没有其他可以做的事情。如果会话没有被放弃,则说明某处存在其他问题(最有可能与客户端有关)。