0

我正在使用 Devise 测试我的网站,我发现如果我在 Devise 注销后拦截重定向,同时调用“销毁”方法,我仍然可以使用后退按钮并重新登录系统.

更多细节:

1)我正在使用带有以下选项的设计::database_authenticable,:recoverable,:trackable,:validatable,:lockable,:timeoutable,:password_archivable,:maximum_attempts => 4,:unlock_strategy =>:none。另外,我使用了 sign_out_all_scopes 的默认设置(true)。

2) 我正在使用 Burp Proxy 拦截从服务器返回到浏览器的调用。

3)我的Session Controller Destroy方法如下:

def destroy
  Rails.logger.info "RESETTING SESSION"
  reset_session

  Rails.logger.info "DESTROYING DEVISE SESSION"
  super
  Rails.logger.info "DONE WITH DEVISE"    
end

日志调用仅适用于我,我也尝试过使用和不使用 reset_session。

4)我以用户身份登录,然后单击我的注销调用,我看到在 Web 服务器上调用了 Destroy 方法(查看日志),但我拦截了对浏览器的调用。

5) 单击后退按钮,我可以返回站点,并且可以像从未退出过一样导航它。

在我看来,尽管在幕后调用了 Warden 的注销,但它实际上会做任何事情,除非 cookie 在浏览器上被销毁。再仔细看看,似乎 Devise 或 Warden 在注销时对数据库没有做任何事情,这意味着注销但不破坏 cookie 无论如何都不会产生任何影响。

我对 Rails 比较陌生,对 Devise 也很陌生,所以我只是错过了什么吗?

编辑:所以在与 Billy Chen 进行了简短的交谈之后,我似乎没有做错任何事,这就是 Devise/Warden 的工作方式。

我很好奇有人如何为他们希望确保注销真的注销用户的网站解决这个问题?在登录/注销时更新的用户对象上添加状态会很容易,但我很好奇为什么在当前设计中没有这样做的选项(即使它只是可选的)。

编辑2:

解决了这个问题。尽管在 User 模型中没有打开 :rememberable,但 devise.rb 文件有“config.use_salt_as_remember_token = true”,删除它可以解决问题。如果模型不允许记忆,不完全确定为什么应该使用该配置,但至少问题得到了解决。

编辑 3:

显然我是个骗子,我刚刚错过了拦截 burp 代理中的响应,这不是固定的。重新测试表明这仍然是一个问题。通过使用密钥标记用户并在注销时将其删除来修复它。一个黑客,但它应该解决这个问题。

4

1 回答 1

0

“销毁”是销毁会话,而不是用户。那么为什么要在这个“破坏”动作中进行数据库操作呢?

当用户登录时,他在登录页面中填写电子邮件和密码,也就是“Session#new”。

当他点击“登录”按钮时,请求被发送到“Session#create”。如果登录信息正确,则会话建立。服务器发送一个包含会话 id 的 cookie,该 cookie 是包含用户 id 的散列。

此后,对于该用户的每个请求,他的浏览器都会连同该 cookie 一起发送请求。服务器解码此哈希并从数据库加载用户 ID。

如果他想注销,他将点击“注销”按钮,该按钮将向“Session#destroy”发送“DELETE”请求,然后服务器将要求他的浏览器从该 cookie 中删除密钥/ID。

现在会话被破坏了。该用户不能再访问登录用户的受保护资源,因为他此后发送的请求将不包含他的有效用户信息。

这基本上就是它的工作原理。您可以在此处查看详细信息:http: //guides.rubyonrails.org/security.html

于 2013-04-15T15:53:16.310 回答