使用Rails进行安全且不安全的会话

时间:2012-02-12 22:39:26

标签: ruby-on-rails session

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

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

如何使用Rails执行此操作?

2 个答案:

答案 0 :(得分:6)

您已经正确地意识到在标准Rails应用程序中混合使用http和https的问题是会话需要不安全(即通过不安全的cookie引用),这意味着它很容易受到会话端的影响。< / p>

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

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

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

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页面。

因此,您的非SSL页面仍然容易受到侧面攻击,但您的SSL页面不容易受到会话侧面的影响。为了使其有效,您必须为所有需要安全的操作强制执行SSL(无论是来自窃听还是来自会话侧面)。在控制器中使用force_ssl是一种方法,或者你可以自己动手。

答案 1 :(得分:3)

在rails中,您可以为任何控制器强制使用SSL:

force_ssl

这会将与控制器操作相关的任何http调用自动重定向到https。这与您想要实现的任何身份验证是分开的。

只需为需要它的控制器实现身份验证,包括非ssl控制器,并对任何需要安全会话的控制器使用force_ssl