cookie安全隱患及防篡改機制


Cookie和Session是為了在無狀態的HTTP協議之上維護會話狀態,使得服務器可以知道當前是和哪個客戶在打交道。本文來詳細討論Cookie和Session的實現機制,以及其中涉及的安全問題。

因為HTTP協議是無狀態的,即每次用戶請求到達服務器時,HTTP服務器並不知道這個用戶是誰、是否登錄過等。現在的服務器之所以知道我們是否已經登錄,是因為服務器在登錄時設置了瀏覽器的Cookie!Session則是借由Cookie而實現的更高層的服務器與瀏覽器之間的會話。

一、cookie安全隱患

Cookie提供了一種手段使得HTTP請求可以附加當前狀態, 現今的網站也是靠Cookie來標識用戶的登錄狀態的:

  1. 用戶提交用戶名和密碼的表單,這通常是一個POST HTTP請求。
  2. 服務器驗證用戶名與密碼,如果合法則返回200(OK)並設置 Set-Cookie 為 authed=true 。
  3. 瀏覽器存儲該Cookie。
  4. 瀏覽器發送請求時,設置Cookie字段為 authed=true 。
  5. 服務器收到第二次請求,從Cookie字段得知該用戶已經登錄。 按照已登錄用戶的權限來處理此次請求。

這里面的問題在哪里?

我們知道可以發送HTTP請求的不只是瀏覽器,很多HTTP客戶端軟件(包括curl、Node.js)都可以發送任意的HTTP請求,可以設置任何頭字段。 假如我們直接設置Cookie字段為authed=true並發送該HTTP請求, 服務器豈不是被欺騙了?這種攻擊非常容易,Cookie是可以被篡改的!

二、cookie防篡改機制

服務器可以為每個Cookie項生成簽名,由於用戶篡改Cookie后無法生成對應的簽名, 服務器便可以得知用戶對Cookie進行了篡改。一個簡單的校驗過程可能是這樣的:

  1. 在服務器中配置一個不為人知的字符串(我們叫它Secret),比如: x$sfz32 。
  2. 當服務器需要設置Cookie時(比如 authed=false ),不僅設置authed的值為false, 在值的后面進一步設置一個簽名,最終設置的Cookie是 authed=false|6hTiBl7lVpd1P 。
  3. 簽名6hTiBl7lVpd1P是這樣生成的: Hash('x$sfz32'+'false') 。 要設置的值與Secret相加再取哈希。
  4. 用戶收到HTTP響應並發現頭字段 Set-Cookie: authed=false|6hTiBl7lVpd1P 。
  5. 用戶在發送HTTP請求時,篡改了authed值,設置頭字段 Cookie: authed=true|??? 。 因為用戶不知道Secret,無法生成簽名,只能隨便填一個。
  6. 服務器收到HTTP請求,發現 Cookie: authed=true|??? 。服務器開始進行校驗: Hash('true'+'x$sfz32') ,便會發現用戶提供的簽名不正確。

通過給Cookie添加簽名,使得服務器得以知道Cookie被篡改。然而故事並未結束。

因為Cookie是明文傳輸的, 只要服務器設置過一次 authed=true|xxxx 我不就知道true的簽名是xxxx了么, 以后就可以用這個簽名來欺騙服務器了。因此Cookie中最好不要放敏感數據。 一般來講Cookie中只會放一個Session Id,而Session存儲在服務器端。

-------------------------------------------------------------------------------------------

本文轉載自:http://harttle.land/2015/08/10/cookie-session.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM