2012-08-05 111 views
5

我希望我的用戶在登錄我的網站時能夠「保持登錄狀態」。在這篇文章的頂部答案"Keep Me Logged In" - the best approach的建議下,我決定將用戶的鹽和密碼組合在一個cookie中,並將用戶的id(數字)存儲在另一個cookie中。當然,哈希值也將存儲在數據庫服務器端,以便在用戶再次返回時進行驗證。我使用的salt值與用戶在第一次註冊時密碼的哈希值相同,因此它是靜態的 - 在會話之間不會改變。我用這種方法看到了一些問題。如何在PHP中安全地存儲包含敏感數據的cookie?

1)使用註冊鹽是一個好主意,如果它是靜態的,或者我應該每次爲cookie生成不同的鹽?

2)如果有人訪問cookie並將它們複製到另一臺計算機上,然後嘗試從該計算機訪問該網站,理論上它會自動將其登錄到該用戶的帳戶,這是不是一個安全問題?

3)在一些有惡意意圖的用戶可以訪問數據庫的情況下,安全的網站會產生鹽漬和散列的密碼,使得黑客很難訪問多個帳戶(如果有的話) 。但是,通過簡單地使用哈希值和salt值並創建一個與他們在數據庫中更改的值匹配的cookie,他們可以有效訪問他們想要的任何帳戶,從而使整個密碼散列過程無用。因此,我現在使用的這種cookie方式正在危及我的整個數據庫和我所有用戶的帳戶。

所以我的問題是,如何在PHP中存儲cookie,並且不需要擔心上述問題等敏感信息,如用戶密碼的散列?當然,Gmail和Hotmail等網站提供這種「保持登錄狀態」功能的方式比我現在做的更安全,因此他們將如何做?

回答

9

不要將密碼存儲在cookie中,不要進行哈希處理。事實上,沒有理由在cookie中存儲任何敏感內容。您需要做的就是將128位(或更大)的隨機ID映射到數據庫中的用戶帳戶,並將該ID存儲在Cookie中。沒有辦法通過遠程蠻力猜測某人是否有效,特別是如果你有停工的地方。

如果有人訪問餅乾,他們將它們複製到另一臺計算機,然後嘗試從該計算機訪問該網站,從理論上講,它會自動記錄他們在該用戶的賬戶,這是不一個安全問題?

是的。這是該功能的缺點。但是,如果您的網站檢測到新的IP地址(特別是來自不同國家/地區)並需要第二步(向移動設備等文本輸入代碼),那麼您需要關注此問題以及密碼被盜的一般問題。 (這當然不能幫助防止本地網絡攻擊,就像不安全的公共WiFi一樣)。

更方便的解決方案是要求「記住我」Cookie使用SSL。這樣黑客就不會以純文本傳輸的方式看到cookie,並且可能需要本地攻擊。 (如果是這樣的話,記住我的cookie可能是用戶關心的最少的部分。)

他們可以有效地訪問他們想要的任何帳戶,使整個密碼散列過程無用。

是的,沒有。如果您使用我描述的技術(隨機ID),那麼他們只能訪問擁有「記住我」Cookie的帳戶。但那就是說,如果他們有權訪問你的數據庫,他們可以強制他們想要的任何帳戶。即使密碼本身很脆弱,即使醃製密碼也很容易破解。

此外,您可以考慮「記住我」登錄是一個半登錄。訪問購買東西,更改電子郵件地址等,仍然需要輸入密碼。做一些無害的事情,比如在留言板上發帖,可以在沒有密碼的情況下完成。

最後,請注意,PHP會話cookie只不過是暫時的「記住我」令牌!這很大程度上適用於會話劫持的概念。 「記住我」令牌只是增加了一個更大的機會窗口。

簡而言之:不要在cookie中存儲任何敏感內容,要求SSL使用cookie,並且如果可能的話,實施多因素驗證......特別是對於管理員帳戶。

+0

很好的答案,謝謝。所以我會使用像uniqid()這樣的東西來生成一個用於記住登錄的令牌。如果數據庫受到攻擊,我仍然不滿意它是如何輕鬆地攻擊帳戶的。如果不包括整個「記住我」的機制,我可能會發現一個入侵行爲,並在發生任何嚴重損害之前採取行動,但採用這種解決方案,攻擊幾乎是瞬間的。 – hesson 2012-08-05 06:36:07

+0

'uniqid()'雖然獨特不是很難預測。我會使用像base64編碼的'openssl_random_pseudo_bytes()'。您的擔憂是有效的,但再次,理智檢查將防止廣泛的攻擊。例如,如果您有許多新的IP登錄到舊賬戶或一個IP登錄到多個賬戶,請舉出一個標誌。 – Matthew 2012-08-05 09:38:58

相關問題