2011-01-27 51 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