理解Cookie和Session機制,及其安全問題

大家常說“Cookie保存在客戶端而Session保存在服務端”,很多人看了有疑惑,明明Session就在Cookie中啊,為什麼這麼說?二者到底有啥區別?

一、Cookie

首先分清Cookies和Cookie

Cookies嚴格來說是個存儲空間,是個載體,用提交持久化的資訊,瀏覽器發送HTTP請求時會自動帶上此域的所有Cookie,抓包能發現就在HTTP Header中

Cookie就是存儲在Cookies中的一條條數據

但當我們說Cookie和Session的區別時,這裡的Cookie就變成了一種和Session一樣的機制,用來比較

網站設計時,服務端可能每次收到請求都需要知道客戶端的某種資訊,比如用戶登錄時間,這種資訊又不足以重要到需要保存在服務端,那麼可以藉助Cookie

數據在服務端生成,生成後通過Set-Cookie發送給客戶端後,服務端自身不保存,當客戶端再次有請求時,服務端可以從請求的HTTP Header中調出這個數據

這能解釋“Cookie保存在客戶端”

二、Session

Session是身份認證的憑證,用戶登錄後,伺服器分發一個憑證,以後用戶再請求帶上這個憑證就能明確身份,不用每次都用帳號密碼來證明身份

這麼重要的數據當然得保存在服務端,且以服務端的為準。但客戶端也得保存,才能在登錄周期中每次請求都帶上

“每次請求都帶上”這顯然就和Cookie一樣,所以就有很多開發者把Session放在Cookie里,不用自己寫前端程式碼把Session塞進請求里,瀏覽器自己會帶上

但Session和Cookie真的一樣么?當然不,這樣設計會帶來安全問題。

三、Session Cookie混用帶來的安全問題

目前的瀏覽器有以下空間供網站使用

  • Cookie:持久保存,大小限制4kb,最多放20個,每次請求都會帶上所有Cookie

  • Session Storage:關閉標籤後失效,請求不會主動帶上

  • Local Storage:持久保存,請求不會主動帶上

我們再來看幾個Web的安全漏洞

  • XSS,跨站腳本攻擊。攻擊者獲得頁面的js許可權,能操作頁面的一切,包括Session Storage和未設置HTTP Only屬性的Cookie

  • CSRF,跨站請求偽造,就是釣魚網站,在網站A,發送一個向網站B的請求,由於瀏覽器會在請求中加上此域的Cookie,所以如果在瀏覽器登錄了網站B,又打開了釣魚網站A,網站A構造的前往網站B的請求就會帶上你的Cookie,如果Cookie中有用戶憑證,伺服器認為你是登錄用戶,請求就會被響應。比如點贊、關注、發色情廣告等請求

防禦XSS,把關機Cookie設置HTTP Only屬性即可,js無權訪問

而防禦CSRF,推薦使用token機制,伺服器頒發token,按規範來說推薦存儲在Session Storage中(也可以放cookie中,由於瀏覽器的同源策略,網站A無法訪問網站B的cookie),js將其添加到請求的參數或Header中

以上兩個措施,都需要做到,才能防護這兩個攻擊。

另外部落客以為,伺服器校驗referer Header也是能防禦CSRF的

四、錯誤示範

  • 把用戶登錄憑證放在Cookie中,未設置HTTP Only,請求中無token參數/Header

    容易遭受XSS、CSRF攻擊

  • 把用戶登錄憑證放在Cookie中,設置了HTTP Only,請求中無token參數/Header

    容易遭受CSRF攻擊,成功防禦XSS攻擊

  • 把用戶登錄憑證放在Cookie中,未設置HTTP Only,請求中有token參數/Header(前端把token保存在Session Storage,保存在Cookies,未設置HTTP Only)

    容易遭受XSS攻擊,攻擊者能構造請求,把token拼上,成功防禦CSRF攻擊

  • 把用戶登錄憑證放在Cookie中,設置了HTTP Only,請求中有token參數/Header【規範防禦】

    成功防禦XSS、CSRF攻擊

  • 把用戶登錄憑證放在Cookie中,未設置HTTP Only,請求中有token參數/Header(前端把token保存在保存在Cookies,設置了HTTP Only)【稀里糊塗地防禦】

    成功防禦XSS、CSRF攻擊

  • 把用戶登錄憑證放在Cookie中,設置了HTTP Only,且請求參數/Header中也添加並校驗此憑證【極簡防禦一】

    一個憑證同時防禦XSS、CSRF攻擊,雖然看起來不正道,不正經

  • 把用戶登錄憑證放在Cookie中,設置了HTTP Only,且伺服器校驗referer Header【極簡防禦二】

    一個憑證同時防禦XSS、CSRF攻擊,瀏覽器js目前似乎無法修改請求的referer頭

五、最後

現在瀏覽器的安全也逐步做上來了,一定程度上能防禦CSRF

以上,講得不對望指正