使用 Rails 进行安全和不安全的会话 [英] Secure and insecure sessions with Rails

查看:35
本文介绍了使用 Rails 进行安全和不安全的会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个电子商务网站,当用户登录时,他们可以使用保存的信用卡数据进行购买.所以,我想使用安全会话.

I have an e-commerce site where when a user logs in, they can make a purchase with saved credit card data. So, I want to use a secure session.

但是,我在网站上有非 SSL 页面,用户也需要在这些页面上登录.所以我也想给这个用户一个不安全的会话.

However, I have non-SSL pages on the site and the user needs to be logged in on those pages too. So I want an insecure session for this user too.

如何使用 Rails 做到这一点?

How can I do this with Rails?

推荐答案

您已经正确地意识到在标准 Rails 应用程序中混合使用 http 和 https 的问题是会话需要不安全(即通过不安全的 cookie 引用),这意味着它容易受到会话侧劫持.

You have correctly realized that the problem with mixing http and https in a standard Rails application is that the session will need to be insecure (i.e. referenced via an insecure cookie), which means it is vulnerable to session side-jacking.

正如您在对@nmott 的回答的评论中提到的,一种方法是同时拥有安全和不安全的 cookie.

As you mentioned in your comment to @nmott's answer, one approach is to have both a secure and an insecure cookie.

对于我的目的,我发现有一个不安全的 Rails 会话和一个仅引用当前登录用户的 user_id 的安全签名 cookie 就足够了,而不是引用两个相同的会话.换句话说,我不需要会话的完整副本,只需要与不安全会话匹配的每个用户(在安全 cookie 中)的唯一内容.

Rather than referencing two identical sessions, for my purposes I find it sufficient to have an insecure Rails session along with a secure signed cookie that merely references the user_id of the currently logged in user. In other words, I don't need a complete copy of the session, just something unique for each user (in a secure cookie) that matches the insecure session.

在通过 SSL 访问的每个操作(并且具有当前用户)中,我检查安全签名 cookie user_id 是否与存储在不安全 Rails 会话中的 user_id 匹配.如果匹配,我假设一切正常,并通过引用不安全的会话正常进行.如果不匹配,则显示错误消息.我使用 before_filter 方法完成此操作,如下所示:

In each action that is accessed via SSL (and has a current user), I check that the secure signed cookie user_id matches the user_id stored in the insecure Rails session. If there is a match, I assume everything is fine and proceed as normal by referencing the insecure session. If there is not a match, then I display an error message. I accomplish this with a before_filter method such as the following:

def verify_secure_user_cookie
  # If we have a current user and the request is SSL, we want to make sure the user
  # has a secure cookie that matches the current user's id.  This prevents attackers
  # from side-jacking a session by obtaining a cookie from a non-SSL request.
  if current_user and request.ssl?
    unless cookies.signed[:user_id] == current_user.id
      raise StandardError, "Invalid secure user cookie"
    end
  end
end

据推测,合法用户将始终拥有安全 cookie,永远不会看到错误消息.攻击者只能复制不安全的 cookie,而无法访问安全 cookie.在这种情况下,他可以对会话进行侧插并访问非 SSL 页面,但他将无法使用受害者的会话访问 SSL 页面.

Presumably, the legitimate user will always have the secure cookie and never see the error message. An attacker would only be able to copy the insecure cookie and would not have access to the secure cookie. In such a case, he could side-jack the session and access non-SSL pages, but he would not be able to access SSL pages using the victim's session.

因此,您的非 SSL 页面仍然容易受到侧向劫持,但您的 SSL 页面不易受到会话侧向劫持.为了使其有效,您必须对需要安全的所有操作(来自窃听或会话侧劫持)强制执行 SSL.在控制器中使用 force_ssl 是实现此目的的一种方法,您也可以自己动手.

Thus, your non-SSL pages are still vulnerable to side-jacking, but your SSL pages are not vulnerable to session side-jacking. For this to be effective, you have to enforce SSL for all actions that need to be secure (either from eavesdropping or from session side-jacking). Using force_ssl in the controller is one way to do this, or you can roll your own.

这篇关于使用 Rails 进行安全和不安全的会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆