轉自http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.htmlhtml
Chrome 51 開始,瀏覽器的 Cookie 新增長了一個SameSite
屬性,用來防止 CSRF 攻擊和用戶追蹤。瀏覽器
Cookie 每每用來存儲用戶的身份信息,惡意網站能夠設法僞造帶有正確 Cookie 的 HTTP 請求,這就是 CSRF 攻擊。安全
舉例來講,用戶登錄了銀行網站your-bank.com
,銀行服務器發來了一個 Cookie。bash
Set-Cookie:id=a3fWa;
用戶後來又訪問了惡意網站malicious.com
,上面有一個表單。服務器
<form action="your-bank.com/transfer" method="POST"> ... </form>
用戶一旦被誘騙發送這個表單,銀行網站就會收到帶有正確 Cookie 的請求。爲了防止這種攻擊,表單通常都帶有一個隨機 token,告訴服務器這是真實請求。cookie
<form action="your-bank.com/transfer" method="POST"> <input type="hidden" name="token" value="dad3weg34"> ... </form>
這種第三方網站引導發出的 Cookie,就稱爲第三方 Cookie。它除了用於 CSRF 攻擊,還能夠用於用戶追蹤。session
好比,Facebook 在第三方網站插入一張看不見的圖片。網站
<img src="facebook.com" style="visibility:hidden;">
瀏覽器加載上面代碼時,就會向 Facebook 發出帶有 Cookie 的請求,從而 Facebook 就會知道你是誰,訪問了什麼網站。spa
Cookie 的SameSite
屬性用來限制第三方 Cookie,從而減小安全風險。code
它能夠設置三個值。
- Strict
- Lax
- None
Strict
最爲嚴格,徹底禁止第三方 Cookie,跨站點時,任何狀況下都不會發送 Cookie。換言之,只有當前網頁的 URL 與請求目標一致,纔會帶上 Cookie。
Set-Cookie: CookieName=CookieValue; SameSite=Strict;
這個規則過於嚴格,可能形成很是很差的用戶體驗。好比,當前網頁有一個 GitHub 連接,用戶點擊跳轉就不會帶有 GitHub 的 Cookie,跳轉過去老是未登錄狀態。
Lax
規則稍稍放寬,大多數狀況也是不發送第三方 Cookie,可是導航到目標網址的 Get 請求除外。
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
導航到目標網址的 GET 請求,只包括三種狀況:連接,預加載請求,GET 表單。詳見下表。
請求類型 | 示例 | 正常狀況 | Lax |
---|---|---|---|
連接 | <a href="..."></a> |
發送 Cookie | 發送 Cookie |
預加載 | <link rel="prerender" href="..."/> |
發送 Cookie | 發送 Cookie |
GET 表單 | <form method="GET" action="..."> |
發送 Cookie | 發送 Cookie |
POST 表單 | <form method="POST" action="..."> |
發送 Cookie | 不發送 |
iframe | <iframe src="..."></iframe> |
發送 Cookie | 不發送 |
AJAX | $.get("...") |
發送 Cookie | 不發送 |
Image | <img src="..."> |
發送 Cookie | 不發送 |
設置了Strict
或Lax
之後,基本就杜絕了 CSRF 攻擊。固然,前提是用戶瀏覽器支持 SameSite 屬性。
Chrome 計劃將Lax
變爲默認設置。這時,網站能夠選擇顯式關閉SameSite
屬性,將其設爲None
。不過,前提是必須同時設置Secure
屬性(Cookie 只能經過 HTTPS 協議發送),不然無效。
下面的設置無效。
Set-Cookie: widget_session=abc123; SameSite=None
下面的設置有效。
Set-Cookie: widget_session=abc123; SameSite=None; Secure