好的,这是一个场景:
现在,在这一点上,Eve有一个被盗的笔记本电脑,它上面存有一个持久性的cookie,它会将她作为Bob登录到mysite.com - 据我所知,这将有效即使Bob改变了密码。
默认情况下,表单身份验证cookie不包含Bob的密码(无论是明文密码,散列密码还是其他加密密码) - 因此Bob的密码根本不涉及cookie身份验证过程,并且上周使用的用户名相同今天仍然会有效。
这是一个容易解决的漏洞 - 通过简单地设置FormsAuthentication.SetAuthCookie(“username:passwordHash”)或其他东西,然后在您的身份验证处理程序中解密和拆分cookie - 但我很难相信这个问题存在'盒子'......我错过了什么吗?
编辑:请注意,我在此假设“记住我”按钮的目的是阻止您每次访问网站时都输入密码。这适用于Facebook,Twitter,Gmail以及我能想到的几乎所有其他网站 - 如果这不是.NET FormsAuthentication中'持久性cookie'选项的目的,我会感到非常惊讶。
此外,是的,我接受在每个传入请求上执行双因素身份验证会产生一定的开销,但实际上,它只比基于他们的数据库从数据库中检索用户稍微贵一点。用户名,你可能还在做什么。
编辑2 :看来至少有一个主要的.NET网站 - CodePlex.com - 容易受此影响;见http://codeplex.codeplex.com/discussions/350646
答案 0 :(得分:9)
也许只接受上次密码重置后发出的FormsAuth票证才有意义。
因此,在Global.asax AuthenticateRequest中,从加密的故障单中提取FormsAuthenticationTicket.IssueDate,并将其与用户上次重置密码的日期进行比较(您需要在重置密码时将其存储在数据库中)。
如果在该日期之前签发了故障单,则拒绝该故障单,不对其进行身份验证并要求他们再次登录。
我自己没有实现这个,所以我可能在理论上错过了一个漏洞...
答案 1 :(得分:1)
在身份验证Cookie中使用哈希密码意味着您必须在每次请求时进行检查。这将是低效的,因为认证可能是昂贵的。
您可以为表单Cookie用户数据部分中的id提供一个简单的“修复”。请注意,如果您自己创建cookie,则可以在其中注入任意数据,例如密码的记录ID。
现在,您可以在AuthenticateRequest
中添加global.asax
处理程序。您尝试从cookie中检索用户数据,并将从cookie中检索到的ID与数据库中的ID进行比较。如果它们不匹配,则返回错误和/或将用户从应用程序中注销。