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






4.84/5 (34投票s)
本文介绍什么是会话劫持以及如何在ASP.NET中防止会话劫持。
引言
本文是我“保护您的ASP.NET和ASP.NET MVC应用程序”系列的第5部分。在本文中,我将详细介绍会话劫持(中间人攻击)究竟是什么,黑客如何利用它以及我们如何在ASP.NET应用程序中防止会话劫持攻击。
下载SessionHijackingPrevention.zip
背景
您可以通过以下链接阅读本系列之前的文章
- 保护您的 ASP.NET 应用程序免受 SQL 注入攻击
- 保护您的 ASP.NET 应用程序免受 XSS 攻击
- 保护您的ASP.NET应用程序免受CSRF攻击
- 保护您的ASP.NET应用程序免受敏感数据泄露和信息泄漏
会话劫持

会话劫持的影响非常严重,攻击者可以做任何经过身份验证的用户被允许在任何网站上做的任何事情。
它是如何被利用的
以下是会话ID可能受到攻击的一些方式
- 在安全性较低的网络上嗅探会话,
- 中间人攻击(系统上安装的任何代理配置,例如:在Fiddler上轻松查看您的流量),
- 从受害者机器上窃取,
- 使用XSS攻击来警报cookie,
- 如果使用基于URL的会话,只需从URL复制和粘贴会话ID。
ASP.NET应用程序演示
为了演示会话劫持,我使用了两个不同的浏览器(Chrome和Mozilla)
不同的程序使用不同的会话。注意:这种攻击通常发生在不同的机器上。
用户登录Chrome并生成了会话ID:(在我的例子中是Chrome)
攻击者嗅探了您的会话ID:(Mozilla)
攻击者现在登录到另一台机器并使用您的会话ID
结果
您知道会话劫持的后果。
如何防止会话劫持
以下是防止ASP.NET应用程序中会话劫持的方法
1. 这个方法的核心是生成一个哈希密钥,其中包含浏览器详细信息、浏览器版本、浏览器平台、用户身份、IP地址(附加/可选)。
并为每个GET和POST请求验证此哈希密钥。
为此,您可以使用Global.asax的Application_BeginRequest
和Application_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