Cookie SameSite

Cookie SameSite Strict, Lax, None Chrome 80 將把 SameSite 預設改為 Lax 的影響

SameSite

說明

  • Chrome 51開始,瀏覽器的新屬性
  • 防止 CSRF 攻擊和用戶追蹤

SameSite屬性

  • Strict: 完全禁止第三方Cookie

    • 只允許 same-site request
    • 最嚴謹方式包括頁面中的 a 頁面點擊連結至 b 頁面 (並不會帶 b 頁面的 cookie)
  • Lax: 大多數情況不發送第三方Cookie,導航到目標網址的Get請求除外

    • 允許 same-site request
    • 比 Strict 寬鬆一些,rfc 上面是寫允許 safe method 像是 top-level navigations (頁面轉導 or 3xx) 的 cross-site request
    • 另外文件指出像是 prerender 可以帶入建立出 same-site request 可帶入 lax cookie
    <link rel='prerender' href="xxx">
* 實際查詢 prrender 功能是 browser 會預先在隱藏的 tab render 頁面,在 redirect 時,會將預載的 tab 進行切換,但有一些限制  [ref](https://www.chromium.org/developers/design-documents/prerender)
* 另外在 chrome 有進行修改,將 prerender 改為 NoState Prefetch 所以看起來這個方式應該無法帶入了
[ref](https://developers.google.com/web/updates/2018/07/nostate-prefetch)

* 所有 cross-site 異步請求都不會帶 cookie
    * `<script>`、`<img>`、`<iframe>`、`XHR`、`Fetch`
  • None: 完全允許
    • None 必須搭配 Secure,否則無效
    • request 必須是 HTTPS 才會帶 Cookie

Chrome 80

    * Blink>Network
        * Cookies default to SameSite=Lax
        * Reject insecure SameSite=None cookies
  • 將預設的 SameSite 改為 Lax 及 None 強制要 Secure (TLS)

如何測試

chrome (beta 及 canary 版本都需要額外開啟) 網址列輸入輸入

chrome://flags

SameSite by default cookies enabled


瀏覽器支援

  • 不支援的 browser 會跟原本一樣 ref
  • This feature is backwards compatible. Browsers not supporting this feature will simply use the cookie as a regular cookie. There is no need to deliver different cookies to clients.
  • ios 12, MAC OS 10.14 兩個版本的 safari SameSite 預設會變成 strict (bug) ref

後端調整部分

  • PHP setcookie method
    • >= 7.3 setcookie 在 7.3 版支援 samesite 的 options
    bool setcookie (
        string $name,
        string $value = "",
        int $expire = 0,
        string $path = "",
        string $domain = "",
        bool $secure = false,
        bool $httponly = false,
        string $samesite = "" // Lax or Strict
    )
* < 7.3 使用 setcookie 的 bug 跳脫的方式進行修改 (`不要用很危險QQ`)
    setcookie('cookie-name', '1', 0, '/; samesite=strict');
  • 直接使用 header 方式設定
    header("Set-Cookie: key=value; path=/; domain=example.net; HttpOnly; SameSite=Lax");
  • 修改 Apache configuration
    Header always edit Set-Cookie (.*) "$1; SameSite=Lax"
  • 修改 Nginx configuration
    location / {
        # your usual config ...
        # hack, set all cookies to secure, httponly and samesite (strict or lax)
        proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
    }

reference