65.9K
CodeProject 正在变化。 阅读更多。
Home

防范会话劫持:保护您的ASP.NET应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (34投票s)

2015年1月4日

CPOL

3分钟阅读

viewsIcon

154517

downloadIcon

1300

本文介绍什么是会话劫持以及如何在ASP.NET中防止会话劫持。

引言

本文是我“保护您的ASP.NET和ASP.NET MVC应用程序”系列的第5部分。在本文中,我将详细介绍会话劫持(中间人攻击)究竟是什么,黑客如何利用它以及我们如何在ASP.NET应用程序中防止会话劫持攻击。

下载SessionHijackingPrevention.zip

背景

您可以通过以下链接阅读本系列之前的文章

  1. 保护您的 ASP.NET 应用程序免受 SQL 注入攻击
  2. 保护您的 ASP.NET 应用程序免受 XSS 攻击
  3. 保护您的ASP.NET应用程序免受CSRF攻击
  4. 保护您的ASP.NET应用程序免受敏感数据泄露和信息泄漏

会话劫持

在解释会话劫持之前,我想说明ASP.NET是如何进行会话管理的。每当创建一个新会话时,就会为该用户生成一个cookie,这个cookie就成为会话ID,因此所有请求都可以使用该会话ID来服务。
 
如果黑客以某种方式能够嗅探或窃取会话ID,他就可以伪造请求作为有效用户(即冒充您)。

 

会话劫持的影响非常严重,攻击者可以做任何经过身份验证的用户被允许在任何网站上做的任何事情。

它是如何被利用的

以下是会话ID可能受到攻击的一些方式

  1. 在安全性较低的网络上嗅探会话,
  2. 中间人攻击(系统上安装的任何代理配置,例如:在Fiddler上轻松查看您的流量),
  3. 从受害者机器上窃取,
  4. 使用XSS攻击来警报cookie,
  5. 如果使用基于URL的会话,只需从URL复制和粘贴会话ID。

ASP.NET应用程序演示

为了演示会话劫持,我使用了两个不同的浏览器(Chrome和Mozilla)
不同的程序使用不同的会话。注意:这种攻击通常发生在不同的机器上。

用户登录Chrome并生成了会话ID:(在我的例子中是Chrome)

攻击者嗅探了您的会话ID:(Mozilla)
攻击者现在登录到另一台机器并使用您的会话ID

结果

您知道会话劫持的后果。

如何防止会话劫持

以下是防止ASP.NET应用程序中会话劫持的方法

1. 这个方法的核心是生成一个哈希密钥,其中包含浏览器详细信息、浏览器版本、浏览器平台、用户身份、IP地址(附加/可选)。
并为每个GET和POST请求验证此哈希密钥。

为此,您可以使用Global.asax的Application_BeginRequestApplication_EndRequest,或者Application_AcquireRequestState

在我的演示中,我使用了Global.asax的Begin和End请求方法。

Application_BeginRequest

步骤1:检查它是否是一个新会话,如果不是,则进行进一步检查
步骤2:检索ASP.NET_SessionID的值
步骤3:为这个POST/GET请求生成哈希密钥,并与之前的ASP.NET_SessionID匹配
步骤4:如果请求有效,则删除您添加到ASP.NET_SessionID中的开销(例如IP地址、浏览器版本、浏览器平台),以便应用程序能够平滑运行。

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            //Check If it is a new session or not , if not then do the further checks
            if (Request.Cookies["ASP.NET_SessionId"] != null && Request.Cookies["ASP.NET_SessionId"].Value != null)
            {
                string newSessionID = Request.Cookies["ASP.NET_SessionID"].Value;
                //Check the valid length of your Generated Session ID
                if (newSessionID.Length <= 24)
                {
                    //Log the attack details here
                    Response.Cookies["TriedTohack"].Value = "True";
                    throw new HttpException("Invalid Request");
                }

                //Genrate Hash key for this User,Browser and machine and match with the Entered NewSessionID
                if (GenerateHashKey() != newSessionID.Substring(24))
                {
                    //Log the attack details here
                    Response.Cookies["TriedTohack"].Value = "True";
                    throw new HttpException("Invalid Request");
                }

                //Use the default one so application will work as usual//ASP.NET_SessionId
                Request.Cookies["ASP.NET_SessionId"].Value = Request.Cookies["ASP.NET_SessionId"].Value.Substring(0, 24);
            }

        } 

Application_EndRequest
只需再次添加哈希密钥并传递给浏览器。

protected void Application_EndRequest(object sender, EventArgs e)
        {
            //Pass the custom Session ID to the browser.
            if (Response.Cookies["ASP.NET_SessionId"] != null)
            {
                Response.Cookies["ASP.NET_SessionId"].Value = Request.Cookies["ASP.NET_SessionId"].Value + GenerateHashKey();
            }
         
        }

要生成哈希密钥,请在您的Global.asax中添加此函数

 private string GenerateHashKey()
        {
            StringBuilder myStr = new StringBuilder();
            myStr.Append(Request.Browser.Browser);
            myStr.Append(Request.Browser.Platform);
            myStr.Append(Request.Browser.MajorVersion);
            myStr.Append(Request.Browser.MinorVersion);
            //myStr.Append(Request.LogonUserIdentity.User.Value);
            SHA1 sha = new SHA1CryptoServiceProvider();
            byte[] hashdata = sha.ComputeHash(Encoding.UTF8.GetBytes(myStr.ToString()));
            return Convert.ToBase64String(hashdata);
        }

2. 另一种防止会话劫持的方法是强制整个网站使用SSL,并确保cookie被标记为安全。
3. 在注销时删除会话ID并使会话过期。

示例:在注销页面中,在该页面的加载时添加此内容

Session.Abandon(); // Session Expire but cookie do exist
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddDays(-30); //Delete the cookie

感谢您阅读本文。或者,您可以从我的git仓库下载完整的代码

https://github.com/sarveshkushwaha/SessionHijackingPreventionAspNet

参考资料和进一步阅读:

http://stackoverflow.com/questions/22880/what-is-the-best-way-to-prevent-session-hijacking
http://dotnet.dzone.com/articles/aspnet-session-hijacking

© . All rights reserved.