CSRF
CSRF(Cross Site Request Forgery, 跨站域請(qǐng)求偽造)的定義且蓬,相信大家都不陌生。它是指攻擊者通過(guò)誘導(dǎo)用戶夺刑,打開(kāi)已精心設(shè)計(jì)好的頁(yè)面后缅疟,發(fā)送請(qǐng)求到某個(gè)網(wǎng)站執(zhí)行某個(gè)操作(修改數(shù)據(jù))的過(guò)程分别。這里有以下三個(gè)前提:
1、用戶已登錄某可信網(wǎng)站(A站存淫,以下所提到的A站都指這里的某可信網(wǎng)站)
2耘斩、A站存在某個(gè)請(qǐng)求,可以修改或保存信息(例如:/saveinfo)
3桅咆、用戶在A站Session過(guò)期前打開(kāi)攻擊者設(shè)計(jì)好的的頁(yè)面括授,并自動(dòng)或觸發(fā)發(fā)送請(qǐng)求(/saveinfo)
看起來(lái)要求聽(tīng)苛刻的,但的確存在這種情況岩饼〖孕椋“即便是大名鼎鼎的 Gmail, 在 2007 年底也存在著 CSRF 漏洞,從而被黑客攻擊而使 Gmail 的用戶造成巨大的損失籍茧“媸觯”
想要了解怎么應(yīng)對(duì)CSRF,先來(lái)看看攻擊者干些什么寞冯。
攻擊者能干什么
因?yàn)槭芡床呗韵拗瓶饰觯粽卟⒉荒苣玫紸站的任何信息(Cookies)和響應(yīng)信息,他只能利用發(fā)送請(qǐng)求時(shí)吮龄,會(huì)帶上cookies去校驗(yàn)登錄信息或權(quán)限的特性俭茧,去修改用戶的數(shù)據(jù),來(lái)達(dá)到攻擊目的漓帚。因此母债,一般用于獲取信息而不涉及到修改信息的請(qǐng)求(Get)就不用擔(dān)心會(huì)有CSRF危險(xiǎn)了,重要的是能修改信息的請(qǐng)求尝抖。當(dāng)然毡们,如果你用Get去修改信息,那就需要考慮防范CSRF了牵署。but這樣做本身就違背了HTTP method設(shè)定的初衷漏隐,同時(shí)Get的攻擊方式更為簡(jiǎn)單,一個(gè)Img標(biāo)簽加上JavaScript就能觸發(fā)奴迅。所以不建議這么做
CRSF預(yù)防措施
正所謂兵來(lái)將擋青责,水來(lái)土掩。了解了攻擊者利用的一些原理取具,就對(duì)應(yīng)的可以找到一些對(duì)應(yīng)措施
1脖隶、在服務(wù)端驗(yàn)證HTTP的Referer字段。
此方法成本較小暇检,只需要在服務(wù)端攔截請(qǐng)求产阱,判斷Referer是否來(lái)自于同一域名,如果不是或者不存在CSRF的話块仆,則認(rèn)為有可能是CSRF攻擊构蹬,直接過(guò)濾王暗。但這種方法也有弊端,那就是當(dāng)有些人會(huì)擔(dān)心Referer會(huì)泄露個(gè)人信息時(shí)(畢竟像服務(wù)器發(fā)送了自己的來(lái)源地址)庄敛。這些人會(huì)嘗試去關(guān)閉Referer俗壹。這樣當(dāng)這些用戶發(fā)起請(qǐng)求時(shí)就不會(huì)帶上Referer,這個(gè)請(qǐng)求就會(huì)被判成有可能的CSRF攻擊藻烤,因?yàn)榘凑丈鲜鲞^(guò)濾規(guī)則绷雏,請(qǐng)求頭中無(wú)Referer的有可能會(huì)是CSRF攻擊。
2怖亭、在請(qǐng)求地址中添加 token 并驗(yàn)證
此方法的核心思想就是涎显,構(gòu)造成什么樣的信息,來(lái)辨別請(qǐng)求是從用戶手中發(fā)出兴猩,還是被攻擊者利用而發(fā)出的期吓,很顯然Cookie不能做到,因?yàn)橛脩艉凸粽叨寄軐⑼瑯拥腃ookie帶到服務(wù)器上峭跳。
答案就是token(令牌)膘婶,它由服務(wù)端通過(guò)一定算法生成,每當(dāng)用戶請(qǐng)求頁(yè)面的時(shí)候蛀醉,則向用戶返回的頁(yè)面中帶上一個(gè)全新的token。下次用戶在發(fā)送請(qǐng)求的時(shí)候衅码,就帶上該token與服務(wù)器的token進(jìn)行對(duì)比拯刁。但這token要放在哪里呢?
三種情況:
1 對(duì)于Get請(qǐng)求逝段,在Url后面動(dòng)態(tài)加上token垛玻。 此方法也有一定約束,頁(yè)面有很多鏈接奶躯,一個(gè)一個(gè)加太麻煩帚桩,就需要在document加載完以后,通過(guò)js來(lái)輔助完成了嘹黔。但這個(gè)方法對(duì)于動(dòng)態(tài)生成的內(nèi)容账嚎,就無(wú)能為力了。
2 Post請(qǐng)求 在form表帶中加上
<pre><code>< input type=”hidden” name=token value=”tokenvalue”/></code></pre>
(查看PC淘寶的個(gè)人中心儡蔓,其修改資料就是用的此方法)由于同源策略郭蕉,攻擊者是拿不到表單里的數(shù)據(jù)的。此方法也跟Get請(qǐng)求有同樣的問(wèn)題喂江,那就是對(duì)于多鏈接和動(dòng)態(tài)生成的內(nèi)容召锈,js批量加上token的辦法就不行了,只能手動(dòng)添加获询。
3涨岁、對(duì)于Ajax請(qǐng)求拐袜,如果跨域,則默認(rèn)不會(huì)帶上A站的cookie梢薪。因此蹬铺,從某些方面來(lái)說(shuō),是相對(duì)安全的沮尿。但是根據(jù)w3c對(duì)Ajax的一個(gè)屬性的描述
4.6.4 The withCredentials attribute
client . withCredentials
True when user credentials are to be included in a cross-origin request. False when they are to be excluded in a cross-origin request and when cookies are to be ignored in its response. Initially false.
大概說(shuō)的意思是丛塌,如果withCredentials為true,則存在跨域請(qǐng)求的時(shí)候畜疾,用戶的credentials(包括cookie赴邻,我是這么理解的,如有錯(cuò)歡迎指正)會(huì)被帶上啡捶。
如果將withCredentials設(shè)為true姥敛,這樣也會(huì)存在上述的安全問(wèn)題,因?yàn)镃ookies在發(fā)送請(qǐng)求的同時(shí)也被戴上了瞎暑。
總結(jié)
1彤敛、攻擊者是利用用戶登錄過(guò)信任網(wǎng)站后,在會(huì)話未過(guò)期之前誘導(dǎo)用戶打開(kāi)有問(wèn)題的網(wǎng)站而達(dá)到攻擊目的的
2了赌、常見(jiàn)的防御措施有校驗(yàn)請(qǐng)求頭的referer墨榄,以及新增攻擊者無(wú)法獲取的隨機(jī)數(shù)token(令牌)來(lái)達(dá)到防御目的的。
3勿她、token存放的地方有多種袄秩,對(duì)于POST請(qǐng)求,則構(gòu)造hideen的input標(biāo)簽逢并;對(duì)于Get則在鏈接后添加token之剧;對(duì)于ajax,則在cookie中添加token砍聊。
4背稼、個(gè)人覺(jué)得相對(duì)安全的做法就是既驗(yàn)證referer,同事也校驗(yàn)token玻蝌。如涉及到更隱秘的操作蟹肘,則需要通過(guò)驗(yàn)證碼或者手動(dòng)輸入密碼來(lái)做防范了。
參考文章:
https://www.w3.org/TR/2014/WD-XMLHttpRequest-20140130/#the-withcredentials-attribute
https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
https://en.wikipedia.org/wiki/Cross-site_request_forgery
第一次寫Post灶伊,過(guò)程如此之多疆前,小到markdown語(yǔ)法;大到發(fā)現(xiàn)問(wèn)題聘萨、探索分析問(wèn)題竹椒、查閱資料并自測(cè)驗(yàn)證。最后通篇檢查米辐,是否存在有問(wèn)題的地方胸完。整個(gè)過(guò)程雖然比較難书释,但這讓自己對(duì)于CRSF有了更深刻的認(rèn)識(shí)。在團(tuán)隊(duì)完成分享后不遺余力整理的一篇赊窥,相信以后會(huì)更好爆惧。