Rails 的安全和不安全会话
我有一个电子商务网站,当用户登录时,他们可以使用保存的信用卡数据进行购买。所以,我想使用安全会话。
但是,我的网站上有非 SSL 页面,用户也需要在这些页面上登录。所以我也希望该用户有一个不安全的会话。
我怎样才能用 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.
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.
How can I do this with Rails?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您已经正确认识到,在标准 Rails 应用程序中混合 http 和 https 的问题是会话需要不安全(即通过不安全的 cookie 引用),这意味着它容易受到会话侧劫持。
正如您在对 @nmott 的回答的评论中提到的,一种方法是同时拥有安全和不安全的 cookie。
就我的目的而言,我发现拥有一个不安全的 Rails 会话以及一个仅引用当前登录用户的 user_id 的安全签名 cookie 就足够了,而不是引用两个相同的会话。换句话说,我不需要会话的完整副本,只需要每个用户(在安全 cookie 中)唯一与不安全会话匹配的内容。
在通过 SSL 访问的每个操作(并且具有当前用户)中,我检查安全签名的 cookie user_id 是否与不安全的 Rails 会话中存储的 user_id 匹配。如果存在匹配,我认为一切正常并通过引用不安全会话正常进行。如果不匹配,我会显示一条错误消息。我使用 before_filter 方法来完成此操作,如下所示:
据推测,合法用户将始终拥有安全 cookie 并且永远不会看到错误消息。攻击者只能复制不安全的 cookie,而无法访问安全的 cookie。在这种情况下,他可以侧劫会话并访问非 SSL 页面,但他无法使用受害者的会话访问 SSL 页面。
因此,您的非 SSL 页面仍然容易受到侧面劫持,但您的 SSL 页面不容易受到会话侧面劫持。为了使其有效,您必须对所有需要安全的操作(防止窃听或会话劫持)强制执行 SSL。在控制器中使用force_ssl 是实现此目的的一种方法,或者您也可以自己推出。
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.
As you mentioned in your comment to @nmott's answer, one approach is to have both a secure and an insecure 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.
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:
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.
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 中,您可以通过以下方式对任何控制器强制使用 SSL:
这会将与控制器操作相关的任何
http
调用自动重定向到https
。这与任何您想要实现的身份验证是分开的。只需对需要它的控制器(包括非 ssl 控制器)实施身份验证,并对任何额外需要安全会话的控制器使用
force_ssl
。In rails you can force SSL for any controller with:
This will auto-redirect any
http
call related to the controller action tohttps
. This is separate from any authentication which would be implemented however you want.Simply implement authentication for the controllers that require it, including non-ssl controllers, and use
force_ssl
for any controllers which additionally require secure session.