samesite設置讓跨域jsonp中cookie無法傳遞問題


最近項目中遇到一個問題,就是a.com域名下使用b.com域名的jsonp獲取數據,竟然無法把b.com的cookie上發。

一)發現問題
 1)確認瀏覽器版本,chrome的83.0.4103.116版本,無法上發跨域cookie
 2)測試其他瀏覽器版本,QQ瀏覽器10.6(Chromium70.0.3538.25),可以正常上發跨域cookie
 3)查找差異性,因為是cookie問題,我們服務端寫cookie是使用php的setcookie方法,所以我們查找php.net官網setcookie方法,我們發現了一個設置值,就是cookie的samesite這個屬性。見后面參考1。

 

二)什么是samesite
 samesite最早出自草案:https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02
 Chrome 51 開始,瀏覽器的 Cookie 新增加了一個SameSite屬性,用來防止 CSRF 攻擊和用戶追蹤。以前samesite默認為None。
 chrome升級到80后,把samesite默認值設為lax,導致了jsonp傳遞cookie的問題。
 我們可以通過chrome的地址訪問:chrome://flags/
 查找samesiite,就可以找到實驗室中的幾個選項,只要禁用第一個選項,就可以上發cookie了。但是有沒有其他不禁用的方法,因為這個版本默認就開啟了,不可能讓用戶來手動設置,所以我們需要了解一下這是個什么東西。

 

 Cookie 的SameSite屬性用來限制第三方 Cookie,從而減少安全風險。
 它可以設置三個值:Strict,Lax和None。

 1)Strict值,嚴格,完全禁止第三方cookie,跨站時,任何情況都不發送cookie。

Set-Cookie: CookieName=CookieValue; SameSite=Strict;

 2) 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 屬性。

 3)None,chrome默認lax,但是我們網站可以顯式關閉SameSite屬性,設置為None既可。但是前提必須設置Secure屬性為true,否則設置無效。

//無效
Set-Cookie: widget_session=abc123; SameSite=None
//有效
Set-Cookie: widget_session=abc123; SameSite=None; Secure

三)php中設置帶SameSite的cookie
 1)服務器通用配置
 1.1)apache通用配置

Header always edit Set-Cookie (.*) "$1; SameSite=Lax"

 1.2) nginx通用配置

location / {
    # your usual config ...
    # hack, set all cookies to secure, httponly and samesite (strict or lax)
    proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
}

 2)PHP >= v7.3,可以直接設置samesite

setcookie($name, $value, [
    'expires' => time() + 86400,
    'path' => '/',
    'domain' => 'domain.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'None',
]);

 3)PHP <v7.3,無法直接設置samesite

//通過header設置
header("Set-Cookie: key=value; path=/; domain=example.org; HttpOnly; SameSite=Lax");
//通過setcookie方法設置,利用path傳入"/;samesite=None",這是利用php的一個bug,不會對path里面的“;”進行處理
setcookie('cookie-name', '1', 0, '/; samesite=strict');

四)參考

 1)php設置cookie方法:

  https://www.php.net/manual/en/function.setcookie.php

 2)php中setcookie的bug可以查看:

  https://github.com/php/php-src/commit/5cb825df7251aeb28b297f071c35b227a3949f01

 3)Cookies:HTTP狀態管理機制草案05:

  https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-05

 4)samesite兼容內容:

  https://www.chromium.org/updates/same-site/incompatible-clients

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM