使用 Restful 身份验证的无意会话劫持问题
Posted
技术标签:
【中文标题】使用 Restful 身份验证的无意会话劫持问题【英文标题】:Inadvertent Session Hijacking Issue With Restful Authentication 【发布时间】:2010-09-13 19:06:10 【问题描述】:我正在使用在 github 上找到的当前版本的 restful_authentication,我遇到了一堆奇怪的会话问题。服务器似乎以某种方式将会话分配给不应该的用户。这只发生在越过注销/登录障碍时。
这是一个例子。在服务器上没有活动会话的情况下,我使用用户 A 登录了一个帐户。在另一台机器上,我使用用户 B 登录。然后当注销用户 B 时,在注销重定向发生后的某个时间,我将登录为用户 A. 从这一点开始,我可以继续浏览该站点,就好像我以该用户身份登录一样!我通过日志观察到的是,当这种劫持发生时,会话 ID 是不一样的。用户 A 在两个会话中都登录了,但会话 ID 完全不同。这只是可能发生的事情的一个例子。我无法可靠地重现该问题,因为它看似随机。
这似乎不是环境或运行它的服务器的症状。我可以使用杂种和乘客重现问题。我也在开发和生产中看到了它。我在这个应用程序中使用基于 db 的会话,它在 Rails 2.1.1 上运行。我在调用生成器时应用了有状态选项。否则,不会对会话的处理方式进行其他修改。
更新 这是直接来自restful_authentication的违规方法。
# Accesses the current user from the session.
# Future calls avoid the database because nil is not equal to false.
def current_user
@current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
end
【问题讨论】:
【参考方案1】:我不知道这是否是一个很好的答案,因为它是一种解决方法。我所做的只是切换到基于 cookie 的会话,一切都很顺利。
【讨论】:
【参考方案2】:这个网站是远程的吗?您是在同一网络上的两台不同的计算机上登录它吗?
【讨论】:
我让它在我的笔记本电脑上的本地开发和服务器上的生产中运行。您对同一网络上的 2 个帐户是正确的。不过,我是在不同机器上的不同浏览器中执行此操作的。【参考方案3】:如果您(或编写 restful_authentication 的人)将当前用户缓存在类变量中,则可能会发生这种情况。我看过一堆提倡使用“User.current_user
”的文章,但是由于类是跨请求缓存的,这可能会导致会话污染。
【讨论】:
这似乎是一个合理的答案,但在从缓存变量的存储中删除 current_user 对象的存储后,我仍然能够重现这种劫持行为。 如果你将当前用户缓存在一个类变量中,你只需要记住在每次请求之前清理它。比如:before filter :clean_user; before_filter :authenticate
以上是关于使用 Restful 身份验证的无意会话劫持问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 RESTful WCF API 中实现 HMAC 身份验证