【科普】關于Cookie的一點知識
- 1. Cookie的傳輸方式
- 2. 不設置Domain時的默認邏輯
- 3. SameSite設置為None的風險
- 4. 通過IP訪問時如何設置Cookie
1. Cookie的傳輸方式
Cookie是通過HTTP(超文本傳輸協議)和HTTPS(安全超文本傳輸協議)頭部在服務器和客戶端之間傳輸的。當服務器想要在客戶端(通常是網頁瀏覽器)上存儲信息時,它會在HTTP響應頭中包含一個Set-Cookie
頭部,這個頭部包含了cookie的名稱、值以及其他可選屬性(如Expires
、Max-Age
、Domain
、Path
、Secure
、HttpOnly
和SameSite
等)。然后,瀏覽器會存儲這些信息,并在之后對該服務器的每次請求中通過HTTP請求頭中的Cookie
頭部將其回傳給服務器。
這是一個服務器響應示例,設置了一個cookie:
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value; Expires=Wed, 09 Jun 2021 10:18:14 GMT
而這是之后客戶端請求服務器時,瀏覽器自動添加的請求頭示例,包含之前設置的cookie:
GET /index.html HTTP/1.1
Host: www.example.com
Cookie: name=value
如果網站通過HTTPS運行,使用Secure
屬性的cookie將通過加密的方式傳輸,增加了數據傳輸過程中的安全性。此外,HttpOnly
屬性可以用來限制cookie僅通過HTTP(S)請求被傳輸,而不能通過客戶端腳本訪問,這有助于減少跨站腳本攻擊(XSS)的風險。
2. 不設置Domain時的默認邏輯
當設置Cookie時,如果沒有為Domain
屬性指定值,默認行為是將Cookie與設置它的服務器的完全限定域名(FQDN)關聯。這意味著,如果沒有明確設置Domain
屬性,Cookie僅會被發送到原始服務器而不會被發送到其他任何子域。
例如,如果您的服務器位于example.com
,并且在設置Cookie時沒有指定Domain
屬性:
Set-Cookie: name=value; Path=/
那么這個Cookie將只對來自example.com
的請求可見。它不會對任何子域(如sub.example.com
)可見。
然而,如果您設置了Domain
屬性為.example.com
(注意域名前的點):
Set-Cookie: name=value; Domain=.example.com; Path=/
這個Cookie則對example.com
及其所有子域(如sub.example.com
、another.sub.example.com
等)可見。這種方式可以讓Cookie跨多個子域共享。
需要注意的是,出于安全考慮,瀏覽器通常不允許將Cookie設置為頂級域名之外的域。例如,如果您嘗試從example.com
設置一個屬于anotherdomain.com
的Cookie,這種設置將會被忽略。此外,一些現代瀏覽器對第三方Cookie(來自不同于當前網頁域的Cookie)有更嚴格的限制,這也需要在設計Cookie策略時考慮。
3. SameSite設置為None的風險
將Cookie的SameSite
屬性設置為None
以允許跨站點請求發送Cookie確實帶來了一些安全風險。SameSite
屬性是用來防止跨站點請求偽造(CSRF)攻擊的,它允許服務器指定某個Cookie不應該隨著來自第三方網站的請求被發送。當SameSite
設置為None
時,Cookie將在所有的請求中被發送,包括跨站點請求,這就增加了下列風險:
-
跨站點請求偽造(CSRF):如果Cookie不受到適當的保護(例如,沒有使用CSRF令牌),那么攻擊者可能會利用用戶的登錄態發起惡意請求。例如,如果用戶登錄了銀行網站,然后訪問了一個惡意網站,那么這個惡意網站可以在不知情的情況下發起跨站點請求,如嘗試轉賬操作。
-
跨站腳本攻擊(XSS):雖然
SameSite=None
本身不直接導致XSS攻擊,但如果配合Secure
屬性未被設置(因為SameSite=None
需要與Secure
一起使用),在非HTTPS環境下,Cookie更容易被攔截。如果攻擊者能夠注入惡意腳本到網頁上,他們可能利用這個漏洞竊取用戶的Cookie。 -
隱私泄露:由于Cookie將在所有的請求中被發送,用戶的一些隱私信息可能會無意中泄露給第三方網站。這可能包括跟蹤用戶行為的Cookie,從而允許第三方創建用戶的詳細行為輪廓。
為了緩解這些風險,網站開發者應該:
- 只在確實需要跨站點Cookie時設置
SameSite=None
,并始終與Secure
屬性一起使用,確保Cookie僅通過安全的HTTPS連接被發送。 - 實施其他安全措施,比如使用CSRF令牌和XSS過濾,以進一步保護網站免受攻擊。
- 審慎考慮哪些信息存儲在Cookie中,避免存儲敏感信息。
4. 通過IP訪問時如何設置Cookie
通過IP地址訪問網站時設置Cookie的方式與通過域名訪問時相同。在HTTP響應頭中使用Set-Cookie
字段來設置Cookie。以下是一個設置Cookie的HTTP響應示例:
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: sessionId=abc123; Path=/; Expires=Wed, 09 Jun 2021 10:18:14 GMT
在客戶端,無論是通過域名還是IP地址訪問,瀏覽器都會處理并存儲服務器發送的Cookie,并在隨后的請求中返回給服務器。
但是,需要注意幾個重要的限制和最佳實踐:
-
安全性:如果您設置了
Secure
屬性,意味著Cookie只能通過HTTPS協議發送。這意味著您的服務器必須配置SSL/TLS,即使是通過IP地址訪問。 -
作用域:通常,Cookie會與特定的域名關聯。如果您通過IP地址設置Cookie,那么Cookie的
Domain
屬性可能無法使用或者其行為可能與期望不同。在這種情況下,Cookie將默認與完全匹配的IP地址關聯。 -
跨域請求:如果您的網站使用了跨域資源共享(CORS)策略,并且您希望通過IP地址訪問時也能發送Cookie,那么您需要確保CORS策略中包含了相應的IP地址,并且請求中包含
credentials
標志。 -
SameSite屬性:如之前討論的,
SameSite
屬性可以控制Cookie的跨站點請求行為。SameSite=None; Secure
將允許Cookie在跨站點請求中發送,但這通常用于具有明確域名的網站。通過IP地址訪問時,依然可以設置這個屬性,但實際上跨站點的概念可能不適用于純IP訪問的情況。
在實際部署時,出于安全和兼容性的考慮,推薦使用域名而不是裸IP地址來服務網站,并通過HTTPS提供服務。如果您必須通過IP地址設置和管理Cookie,那么您可能需要格外注意安全配置和測試,以確保一切按預期工作。