2009-09-12 101 views
4

我做了一個登錄/註銷類,用戶登錄,根據用戶的選擇設置cookie。用戶輸入他們的電子郵件/密碼,並檢查數據庫,電子郵件/密碼組合存在一個會話創建,並設置cookie(與用戶ID),用戶被重定向...然後我有一個功能,記錄用戶通過獲取保存在該cookie中的用戶標識,檢查該用戶標識是否存在,然後再將用戶數據保存在會話中......我想知道是否有人看到任何潛在的錯誤/不安全的事情。什麼類型的信息應該保存在一個Cookie(PHP)

簡短的例子,我確定你們可以得到它的要點...

function login($email, $password, $remember){ 
    // Check the database for email/password combo 
    if(/*user exists*/){ // if the user exists 
    $_SESSION = /*User data*/ // save the users data in a session 
    if($remember){ 
     setcookie('user_id', /*User id*/); // save the user id in a cookie 
    } 
    header("location: index.php");// redirect 
    } 
} 

function Check_Cookie(){ 
    if(isset($_COOKIE['user_id'])){ 
    return $this->Log_In_ID($_COOKIE['user_id']); 
    }else{ 
    return false 
    } 
} 

function Log_In_ID($id){ 
    //Check the database if the user id exists 
    if(/*user exists*/){ // if the user exists 
    $_SESSION = /*User data*/ // save the users data in a session 
    header("location: index.php");// redirect 
    }else{ 
    return false; 
    } 
} 

它不是什麼即時試圖問一個具體的例子,但是我相信你能得到它的要點。 ..有沒有人看到任何可能與此有關的錯誤。如果你們有任何建議,我喜歡聽到他們......還有,你們是否使用oop登錄用戶或以任何其他方式登錄用戶。

回答

8

如果你的用戶ID是一個連續的數字,這是非常不安全的,因爲任何人都可以根據自己的cookie更改他們的cookie爲另一個合理的數字(例如,如果我的是1274,我可以嘗試在該範圍內的其他數字)並立即欺騙該用戶。

您最好分配一個與該用戶關聯的臨時ID,如GUID。由於GUID具有天文獨特性並且幾乎可以防碰撞,所以它們也幾乎不可能從系統外部猜測或預測。

當用戶登錄,創建一個新的GUID並存儲與用戶:

UserID  TokenID          Expires 
1274   {3F2504E0-4F89-11D3-9A0C-0305E82C3301}   9/25/2009 12:00:00 

當用戶返回時,由令牌查找他們的用戶ID,確保令牌沒有過期並記錄它們。然後更改它們的標記。這確保您對以下內容:

  • 攻擊者無法猜測其他用戶的令牌和欺騙他們
  • 令牌到期不能忽視cookie的有效期來規避
  • 因爲令牌不斷變化,即使攻擊者不設法訪問用戶的cookie,接管機會的窗口非常小。
+1

除此之外,您還可以檢查用戶的IP地址是否在相同的範圍和瀏覽器字符串中以確保它是同一臺計算機。 – 2009-09-12 21:05:41

+0

@Milan很好的建議 - 也是很好的檢查,儘管IMO稍微超出了這個特定問題的範圍。 – 2009-09-12 21:08:49

+0

好的解決方案,雷克斯。 另一種選擇是僅依靠cookie的會話id - 假設你有對會話設置的控制和理解。沒有很長的理由不能設置很長的會話壽命。 您的解決方案仍然優越,因爲您正在切換令牌 - 儘管您可以爲每個請求設置最後訪問Cookie,並且如果用戶的「session」已經「足夠長」,請重新生成用戶的sessionid。 – timdev 2009-09-13 06:03:34

0

Cookie很容易被改變 - 所以如果你只是存儲ID,用戶可以改變它。通過猜測他們可以訪問其他帳戶,甚至可能獲得管理員訪問權限。通常,我使用Cookie進行身份驗證時,會將ID與令牌一起存儲。

你可以拿一個哈希的ID和一個鹽值並存儲它 - 然後你可以在用戶連接時驗證令牌。這並不完美,對於高安全性網站有更多考慮 - 但對於標準網站來說應該是一個好的開始。

另一個策略是存儲的長的唯一的會話ID,並用它來記錄用戶回。

1

你不應該相信的cookie數據。如果我編輯我的cookie並將我的ID設置爲「1」(可能是管理用戶),會發生什麼情況?

基本上,不要這樣做。

如果你想要一個「記住我」類型的函數,只需在cookie中保存一個用戶名,這樣你就可以在用戶返回時預填充登錄表單 - 但強制他們重新驗證。

+0

顯然不是所有的網站都是這樣的嚴酷,並且仍然足夠安全。我認爲問題在於如何在用戶中實現這種輕鬆的水平。 – 2009-09-12 20:52:58