使aspx身份验证cookie失效

9

我有一个asp.net web表单。当用户进行身份验证时,它会创建一个名为.aspxauth的安全cookie。

在注销时,我调用这两个方法:

FormsAuthentication.SignOut(); 
Session.Abandon()

问题是我们进行了渗透测试,如果我窃取cookie,注销并手动重新插入cookie,我会再次登录。因此,.aspauth在服务器端未被使无效。

我已经搜索过了,但无法找到解决这个安全漏洞的答案。


您无法将其停用。Session.Abandon()将从用户中删除它,而不是从浏览器/客户端中删除。 - Avijit
1
好的,那么这个cookie重放漏洞没有解决方案吗?我不想改变整个代码来切换到会员类。 - Yannick Richard
1
我的意思是,一定有一种方法可以告诉服务器一个会话令牌现在已经失效了吧?!! - Yannick Richard
我猜这个问题还没有解决?那么解决的方法是使sessionID无效吗?这里有一篇不错的文章如何保护你的ASP.NET Azure Web App - krypru
4个回答

4

Microsoft已经在这里确认了这个问题:https://support.microsoft.com/en-us/kb/900111

他们提供了几种缓解此漏洞的方法:

  1. 通过使用SSL保护应用程序
  2. 强制执行TTL和绝对过期
  3. 在ASP.NET 2.0中使用HttpOnly cookies和表单身份验证
  4. 在ASP.NET 2.0中使用Membership类

关于最后一种方法,我将粘贴网站上的内容以方便保存:

当您在ASP.NET 2.0中实现表单身份验证时,您可以选择将用户信息存储在Membership提供程序中。这个选项是介绍在ASP.NET 2.0中的一个新功能。MembershipUser对象包含特定用户。

如果用户已登录,则可以将此信息存储在MembershipUser对象的Comment属性中。如果您使用此属性,可以开发一种机制来减少ASP.NET 2.0中的cookie重放问题。此机制将按照以下步骤进行:

  1. 创建一个挂钩PostAuthenticateRequest事件的HttpModule。
  2. 如果HttpContext.User属性中有一个FormsIdentity对象,则FormsAuthenticationModule类将识别表单身份验证票证为有效。
  3. 然后,自定义HttpModule类获取与已验证用户相关联的MembershipUser实例的引用。您检查Comment属性以确定用户当前是否已登录。

重要提示:必须在Comment属性中存储指示用户明确注销的信息。此外,当客户最终再次登录时,必须清除Comment属性中的信息。

如果Comment属性指示用户当前未登录,则必须执行以下操作:

  1. 清除cookie 。
  2. 将Response.Status属性设置为401。
  3. 调用Response.End方法,这将隐式地将请求重定向到登录页面。

使用此方法,只有在用户未明确退出并且表单身份验证票证尚未过期时才会接受表单身份验证cookie。


3

2
这不是一个有效的解决方案。主要问题在于会话ID在用户退出登录后仍然在服务器端保持活动状态。如果攻击者可以访问cookie(正如@Yannick Richard在上面报告的那样),添加另一个带有独立“身份验证令牌”的cookie并不能使任何东西更安全。攻击者随后可以窃取两个cookie,我们将回到原点。 - Synctrex

0

这在.NET Framework中仍然是一个问题。每个人似乎都认为Session.Abandon()是答案,但悲惨的事实是该命令不会使服务器端的会话失效。只要拥有正确的令牌值,任何人都可以恢复已经结束的会话,直到会话根据Web.config设置过期(默认=20分钟)。

一个类似的提问者很久以前在这里提出了这个问题: ASP.NET中的会话固定

大多数链接都已经失效,微软也没有关于这个主题的新消息。 https://forums.asp.net/t/2154458.aspx?Preventing+Cookie+Replay+Attacks+MS+support+article+is+now+a+dead+link

更糟糕的是,即使您正在实现完全无状态的MVC应用程序并且不使用Session对象在视图之间存储数据,您仍然容易受到cookie重放攻击的影响。您甚至可以在web.config设置中关闭会话状态,仍然可以重放cookie以访问已注销的会话。
真正的解决方案有些hack-y,并在此处描述,您需要启用InProc会话数据才能使用它。
  • 当用户登录时,在session数据中设置一个布尔值,如Session["LoggedIn"] = true;,该值将存储在服务器端。
  • 当用户退出时,将该值设置为false
  • 在每个请求上检查会话值--试图重放会话的攻击者不会对您友善,并且不仅通过登录页面进行攻击。最简单的方法可能是使用自定义过滤器并在global.asax文件中全局注册(这样您就不必在各处复制代码或在每个控制器/方法上添加属性)。

即使攻击者拥有所有cookie值,也无法重新使用相同的会话ID,一旦达到指定的超时时间,服务器将自动删除它。


-2
if you are using the FormsAuthentication, you can use this code. By using this code you can destroy the created cookies by setting the Expire property of HttpCookie. It will help you:
FormsAuthentication.SignOut();
Session.Clear();
Session.Abandon();
Session.RemoveAll();
// clear authentication cookie
HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, "");
httpCookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(httpCookie);

1
这根本没有解决cookie重放问题。这只是一种更复杂的方式,要求远程浏览器丢弃它所拥有的密钥。 - Mark
@Mark:我的意图是帮助Yannick,使得我的答案可以帮助他以更安全、更健壮的方式删除cookies。感谢您的反馈! - nitin27verma
1
这很公正,但它并没有回答真正的问题。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接