Rails 登录重置会话
Posted
技术标签:
【中文标题】Rails 登录重置会话【英文标题】:Rails Login Reset Session 【发布时间】:2011-06-16 07:35:54 【问题描述】:当用户成功登录时调用 reset_session 并在用户注销时再次调用它是最佳做法吗?这样做有什么副作用/问题吗?
【问题讨论】:
【参考方案1】: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])
old_values = session.to_hash
reset_session
session.update old_values.except('session_id')
session[:athlete_id] = athlete.id
redirect_to root_url, notice: "Authentication successful!"
else
flash.now.alert = "Invalid credentials"
render "new"
end
end
请注意,如果您希望保留任何数据,请务必在重置之前复制会话。
就注销时调用 reset_session 而言,是的,这也是最佳实践。
【讨论】:
在 Rails 5 中,session.replace
将不再工作。但是,您可以使用 old_values = session.to_hash
获取旧值并使用 session.update(old_values)
将它们恢复到新会话。
@Ritchie 这不是复制了session_id
吗?这是故意的吗?
不,你是对的。我不确定它有什么危害。让我们把它改成old_values = session.to_hash
和session.update old_values.except('session_id')
。【参考方案2】:
这实际上取决于您在会话中存储内容的方式以及您希望安全性如何运行。
重置会话将删除用户会话中的所有内容,因此如果他们跳回登录屏幕并重新登录,但仍然(例如)将购物车存储到他们的会话中,您将清除这可能是不受欢迎的.
如果您不存储您认为用户可能想要保留的任何数据,我知道在处理登录尝试之前清除会话完全不会有任何伤害,我建议您在注销时这样做。
【讨论】:
我大体上同意这个回复,但值得注意的是下面的@rbhitchcock 回复,特别是关于会话固定的安全指南参考。【参考方案3】:我认为在用户登录时重置会话是一种很好的做法。这样,恶意个人无法在客户端的连接被加密之前嗅出他们的会话 cookie,并且在他们通过 https 使用登录表单后仍然使用它.试试:
temp = session
reset_session
session.reverse_merge!(temp)
这样,session 获得了由 reset_session 生成的新值,但任何其他 session 变量保持不变。
【讨论】:
这真的有效吗?在 Rails 2 中,当我尝试从会话中取出数据、调用 reset_session 并将数据重新分配回会话时,在下一次请求时它全部消失了。【参考方案4】:由于 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
【讨论】:
以上是关于Rails 登录重置会话的主要内容,如果未能解决你的问题,请参考以下文章