導(dǎo)讀
本文可以幫助你解決以下問題
- 想要了解一下SameSite屬性(產(chǎn)生背景以及各個(gè)屬性)
- 種跨域cookie有問題侦铜,猜測可能是SameSite引起的,需要解決
CSRF攻擊
??要了解SameSite產(chǎn)生的背景遮晚,我們先要了解一下CSRF攻擊。如果你對(duì)此部分不敢興趣拦止,可以直接看SameSite部分县遣。
什么是CSRF
??CSRF(Cross-site request forgery)跨站請(qǐng)求偽造:攻擊者誘導(dǎo)受害者進(jìn)入第三方網(wǎng)站,在第三方網(wǎng)站中创泄,向被攻擊網(wǎng)站發(fā)送跨站請(qǐng)求。利用受害者在被攻擊網(wǎng)站已經(jīng)獲取的注冊(cè)憑證括蝠,繞過后臺(tái)的用戶驗(yàn)證鞠抑,達(dá)到冒充用戶對(duì)被攻擊的網(wǎng)站執(zhí)行某項(xiàng)操作的目的。
??一個(gè)典型的CSRF攻擊有著如下的流程:
*受害者登錄a.com忌警,并保留了登錄憑證(Cookie)搁拙。
*攻擊者引誘受害者訪問了b.com。
*b.com 向 a.com 發(fā)送了一個(gè)請(qǐng)求:a.com/act=xx法绵。瀏覽器會(huì)默認(rèn)攜帶a.com的Cookie箕速。
*a.com接收到請(qǐng)求后,對(duì)請(qǐng)求進(jìn)行驗(yàn)證朋譬,并確認(rèn)是受害者的憑證盐茎,誤以為是受害者自己發(fā)送的請(qǐng)求。
*a.com以受害者的名義執(zhí)行了act=xx徙赢。
*攻擊完成字柠,攻擊者在受害者不知情的情況下探越,冒充受害者,讓a.com執(zhí)行了自己定義的操作窑业。
??我先舉一個(gè)CSRF攻擊的例子吧钦幔,如果你對(duì)CSRF攻擊還不太了解的話,可以先參考前端安全系列(二):如何防止CSRF攻擊常柄?這篇文章鲤氢,再來看這個(gè)案例,我們此次的案例是模擬百度地圖的收藏操作西潘。
我們搜索一家店鋪卷玉,然后我們點(diǎn)擊收藏操作,在chrome控制臺(tái)分析一下發(fā)出的請(qǐng)求秸架。
??很明顯揍庄,這是一個(gè)post請(qǐng)求,貌似是用cookie來驗(yàn)證登陸信息的东抹,并且content-type為application/x-www-form-urlencoded蚂子。那么正好,我們可以新建一個(gè)網(wǎng)站缭黔,利用post表單來模擬一下此次CSRF攻擊請(qǐng)求食茎。假設(shè)場景是:我在用自己的賬號(hào)登陸了百度地圖,然后閑的沒事兒馏谨,去某個(gè)小說網(wǎng)站看了會(huì)兒小說别渔,然后一回來,突然發(fā)現(xiàn)自己關(guān)注了這一家串串店鋪惧互,我很疑惑哎媚,我并沒有點(diǎn)擊收藏,但是為什么收藏了這家店鋪呢喊儡?
??后來我查閱大量資料拨与,最后得出結(jié)論,是這家小說網(wǎng)站存在問題艾猜,這家網(wǎng)站的html代碼如下所示买喧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<form action="https://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=direct&pcevaname=pc4.1&qt=fav&mode=add&type=favdata&lastver=1726297598" method="post">
<input type="text" name="data" value='{"type":"10","sourceid":"aaf0ade9a5d29f9dc62ba16a","plateform":3,"fromapp":"百度地圖","extdata":{"name":"吃鬧熱火鍋串串","geoptx":"12962784.59","geopty":"4829524.68"}}'/>
<input type="text" name="validate" value="58241"/>
<input type="submit" value="Submit"/>
</form>
<div>
小說《斗破蒼穹》此處省略幾百萬字
</div>
<script>
document.forms[0].submit();
</script>
</body>
??上面的html代碼中,這個(gè)小說網(wǎng)站利用form表單的post請(qǐng)求發(fā)起了一個(gè)CSRF攻擊匆赃,模擬了用戶點(diǎn)擊收藏的行為淤毛,并且騙過了服務(wù)端,成功收藏了這家店鋪算柳。
??具體過程如下:當(dāng)用戶登陸了百度地圖以后低淡,百度地圖域名下會(huì)種上用戶登陸信息的cookie,每次對(duì)百度地圖域名發(fā)起請(qǐng)求時(shí),瀏覽器會(huì)默認(rèn)帶上這個(gè)cookie查牌,服務(wù)端以cookie來校驗(yàn)請(qǐng)求發(fā)起人的身份事期。也就是說,小說網(wǎng)站對(duì)百度地圖這個(gè)域名發(fā)起請(qǐng)求纸颜,也會(huì)帶上用戶登陸信息cookie兽泣,再加上post表單并沒有跨域限制,所以最后成功模擬了用戶的收藏操作胁孙。
??這是不是很荒唐唠倦,如果你有興趣去嘗試一下的話,會(huì)發(fā)現(xiàn)很多網(wǎng)站其實(shí)也存在著這種安全問題涮较,為了防止這種攻擊行為稠鼻,chrome很早就推出了cookie的SameSite屬性來限制第三方cookie,但是大家伙都不理不睬狂票。所以chrome干脆一不做二不休候齿,在chrome80版本以后默認(rèn)把cookie的SameSite屬性設(shè)置為Lax,以此來對(duì)第三方cookie做一些限制闺属,這樣就能大大地降低被CSRF攻擊的風(fēng)險(xiǎn)了慌盯。
??但是chrome也很頭疼,因?yàn)榇舜螐?qiáng)制更新SameSite的默認(rèn)策略掂器,勢(shì)必會(huì)給不少使用第三方cookie的系統(tǒng)造成大麻煩亚皂,所以chrome在年前就在控制臺(tái)給出了黃色警告,此次chrome更新SameSite默認(rèn)策略對(duì)于這些有使用第三方cookie場景的系統(tǒng)国瓮,往往會(huì)造成登陸異常灭必,系統(tǒng)崩潰等大問題。
SameSite屬性介紹
??SameSite是cookie的一個(gè)屬性乃摹,用來限制第三方Cookie禁漓。可以參考阮一峰老師的Cookie 的 SameSite 屬性孵睬,或者直接看我畫的下圖播歼。簡單來說他有三個(gè)值:
Strict(禁止第三方 cookie)
Lax(稍微嚴(yán)格一點(diǎn))
-
None (注意,cookie的SameSite設(shè)置為None以后肪康,Secure需要同時(shí)設(shè)置為true荚恶,這意味著你的網(wǎng)站必須支持https)
圖七 SameSite策略
??Chrome80以后撩穿,cookie默認(rèn)的SameSite策略是Lax磷支。大家可以參考圖一中的畫出的SameSite為Lax時(shí)對(duì)第三方cookie的禁止情況,如果你有在POST表單食寡,iframe雾狈,AJAX,Image這些場景中使用第三方cookie的情況抵皱,那么就需要注意了善榛。
問題分析
??包括登陸在內(nèi)的很多信息都是存儲(chǔ)在Cookie當(dāng)中辩蛋,但是瀏覽器的默認(rèn)策略是允許第三方網(wǎng)站發(fā)起的請(qǐng)求中攜帶cookie,這樣就會(huì)很容易遭到CSRF攻擊移盆。
??Chrome瀏覽器從80版本開始更新默認(rèn)的SameSite策略悼院,新的策略為:在所有的 Cookie 中默認(rèn)設(shè)置 SameSite=Lax 來屏蔽部分第三方 Cookie。
??如果你正在使用Chrome瀏覽器咒循,沒有上線也沒有更新据途,但是某天突然遇到第三方請(qǐng)求的cookie沒有種上(比如登陸cookie沒有種上,導(dǎo)致用戶登陸不上)的情況叙甸,那你可能就需要考慮是不是Chrome80以后正在實(shí)行的新版SameSite策略造成的問題了。
案例
??B站的html代碼如下,iframe的src指向A站(SameSite.a.com)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<iframe src="http://SameSite.a.com" frameborder="0"></iframe>
</body>
??比如A網(wǎng)站作為iframe嵌入在B網(wǎng)站中钢属。某天我們突然發(fā)現(xiàn)在B網(wǎng)站中加載A網(wǎng)站的iframe時(shí)我們發(fā)起請(qǐng)求來setCookie必峰,但是cookie并沒有種上。
??大致情況我們可以結(jié)合圖二與圖三來看僚祷,A站作為iframe嵌入在B站中佛致,在B站中訪問iframe(A站)時(shí)想要發(fā)起請(qǐng)求setCookie,但是失敗久妆。
??以登陸信息(圖中為loginToken)舉例晌杰,大多數(shù)系統(tǒng)在用戶訪問時(shí)如果登陸信息校驗(yàn)失敗,就會(huì)發(fā)起登陸請(qǐng)求筷弦,登陸請(qǐng)求setCookie的同時(shí)又會(huì)重定向到系統(tǒng)肋演,所以頁面可能就會(huì)反復(fù)跳轉(zhuǎn)刷新,進(jìn)入死循環(huán)烂琴。
??如果出現(xiàn)第三方請(qǐng)求setCookie失效的情況爹殊,那么我們就可以使用以下操作來驗(yàn)證是否為SameSite的問題。
步驟如下:
Chrome瀏覽器地址欄輸入 chrome: //flags/
找到:SameSite by default cookies奸绷、Cookies without SameSite must be secure
-
設(shè)置上面這兩項(xiàng)設(shè)置成 Disable梗夸,重啟瀏覽器
圖十 chrome設(shè)置
??此時(shí)我們?cè)俅悟?yàn)證網(wǎng)頁之前所存在的問題,如果問題解決了号醉,說明你的瀏覽器確實(shí)存在SameSite策略的問題反症。
解決方法
??如果你依然想采用http域名的話,可以使用方案一畔派;如果方案一不可行的話铅碍,就升級(jí)到https。
方案一:統(tǒng)一主域名
??將A網(wǎng)站與B網(wǎng)站的主域名統(tǒng)一线椰,比如我們可以將A網(wǎng)站由SameSite.a.com變?yōu)镾ameSite.b.com胞谈,與B網(wǎng)站test.b.com保持一致。當(dāng)然,如果采取這種方法的話烦绳,需要重新申請(qǐng)域名卿捎,并且原有的域名都需要重定向到新域名。
方案二:升級(jí)https
SameSite設(shè)置
??A網(wǎng)站的請(qǐng)求中径密,cookie的設(shè)置應(yīng)該帶有Secure; SameSite=None這兩個(gè)屬性
域名升級(jí)https午阵。
??你可能需要對(duì)項(xiàng)目進(jìn)行整體改造,比如將所有http的請(qǐng)求替換為https享扔。
特別注意:
- SameSite=None需要只對(duì)chrome80以上版本進(jìn)行設(shè)置趟庄,原因在于chrome51-chrome66以及其他某些瀏覽器不接受SameSite=None 。
- 如果網(wǎng)站存在http與https同時(shí)使用的情況伪很,需要對(duì)此做兼容戚啥,只有https的時(shí)候才設(shè)置Secure;SameSite=None。原因在于當(dāng)Secure設(shè)置為true時(shí)锉试,表示創(chuàng)建的 Cookie 會(huì)被以安全的形式向服務(wù)器傳輸猫十,也就是只能在 HTTPS 連接中被瀏覽器傳遞到服務(wù)器端進(jìn)行會(huì)話驗(yàn)證。
最后
??即使我們此次不設(shè)置SameSite為Strict或者Lax呆盖,我們也應(yīng)該思考如何去預(yù)防CSRF攻擊拖云,因?yàn)镾ameSite設(shè)置為None的話,意味著第三方網(wǎng)站能發(fā)送攜帶cookie的請(qǐng)求应又,就如文章一開始舉例的CSRF攻擊一樣宙项。
小結(jié)
??我們首先介紹了SameSite屬性產(chǎn)生的背景以及為何chrome要做此次SameSite默認(rèn)策略的升級(jí),然后講解了SameSite對(duì)應(yīng)的三個(gè)屬性具體限制了哪些第三方cookie株扛,最后舉了一個(gè)chrome此次升級(jí)造成系統(tǒng)異常的案例尤筐,給出了具體的解決方案。
??chrome一直如此關(guān)注安全問題洞就,逼迫著我們做系統(tǒng)改造升級(jí)盆繁,我們也應(yīng)該反思,多做一些工作來提高我們系統(tǒng)的安全性旬蟋。