2011-01-27 68 views
15

是不是最好的做法叫reset_session当用户成功签署并再次调用它,当用户退出?这样做有任何副作用/问题吗?Rails的登录会话重置

回答

12

这真的要取决于你如何存储在会话的东西,你想怎么的安全运行。

重置会话会放弃用户会话中的所有内容,因此如果他们跳回到登录屏幕并重新登录但仍然有(例如)将购物车存储到其会话中,则您将清除可能是不可取的。

如果您没有存储任何您认为用户可能想要保留的数据,我知道在处理登录尝试之前清除会话没有任何理由会导致伤害,我建议您签名。

+0

我大体上同意这个回应,但是值得注意的是@rbhitchcock下面的回应,特别是安全指南参考会话固定。 – 2013-05-25 14:25:09

7

我认为这是很好的做法,重置会话当用户登录时,只有这样,恶意的人不能在客户端的连接进行加密之前嗅出了自己的会话cookie和他们仍然在使用该标志的形式后使用HTTPS。尝试:

temp = session 
reset_session 
session.reverse_merge!(temp) 

这样,会话获取由reset_session生成的新值,但其他任何会话变量保持不变。

+0

这实际上工作吗?在Rails 2中,当我尝试从会话中获取数据,调用reset_session并将数据重新分配给会话时,在下一个请求中,它全部消失。 – 2012-07-24 23:05:26

13

Ruby on Rails Security Guide建议在成功验证后重置会话ID以防止session fixation漏洞。从本质上讲,会话固定涉及攻击者设置你的会话ID(或能够知道ID是什么,当你打的登录页面的一些其他方法),并根据您的身份验证成功,攻击者使用设置Cookie为自己的浏览器您的会话ID并随后通过身份验证。成功验证后重置会话ID完全可以减轻此类漏洞。在创建操作一些示例代码可能是:

def create 
    user = User.find_by_email(params[:email]) 
    if user && user.authenticate(params[:password]) 
    temp_session = session.dup 
    reset_session 
    session.replace(temp_session) 
    session[:athlete_id] = athlete.id 
    redirect_to root_url, notice: "Authentication successful!" 
    else 
    flash.now.alert = "Invalid credentials" 
    render "new" 
    end 
end 

注意,在重新设定它是否有您希望保留的任何数据之前复制的会议是非常重要的。

至于在注销调用reset_session,是的,这也是最好的做法也是如此。

+2

在Rails 5中,`session.replace`将不再起作用。但是,您可以使用`old_values = session.to_hash`获取旧值,并使用`session.update(old_values)`将它们恢复到新会话。 – Ritchie 2016-12-22 08:29:34

0

很多这里的答案并没有因Rails的API改变,所以我就离开这里一个的作品至少Rails的5.0岁好。

正如其他人注意到Rails安全指南recommends在登录时调用reset_session以避免会话修复攻击。

您可能需要您的会议上登录清零,但如果你只是想改变会话ID并保留一切(即没有副作用),你可以做这样的:

def mitigate_session_fixation 
    old_values = session.to_hash 
    reset_session 
    session.update old_values.except('session_id') 
end