一、什么是CSRF漏洞?
CSRF跨站請(qǐng)求偽造,主要表現(xiàn)為:攻擊者盜用了你的身份,以你的名義發(fā)送惡意請(qǐng)求,對(duì)服務(wù)器來(lái)說(shuō)這個(gè)請(qǐng)求是完全合法的,但是卻完成了攻擊者所期望的一個(gè)操作,例如以你的名義發(fā)送郵件或消息,盜取你的賬號(hào),添加系統(tǒng)管理員,甚至于購(gòu)買商品、虛擬貨幣轉(zhuǎn)賬等。
CSRF現(xiàn)狀:CSRF這種攻擊方式在2000年已經(jīng)被國(guó)外的安全人員提出,但在國(guó)內(nèi),直到06年才開(kāi)始被關(guān)注,08年,國(guó)內(nèi)外的多個(gè)大型社區(qū)和交互網(wǎng)站分別爆出CSRF漏洞,如:NYTimes.com、Metafilter(一個(gè)大型的BLOG網(wǎng)站),YouTube和百度。而現(xiàn)在,互聯(lián)網(wǎng)上的許多站點(diǎn)仍對(duì)此毫無(wú)防備,以至于安全業(yè)界稱CSRF為“沉睡的巨人”。
二、CSRF漏洞是如何攻擊的?
(1)受害者登錄AA.com,并保留了登錄憑證(Cookie)
(2)攻擊者引誘受害者訪問(wèn)了BB.com
(3)BB.com 向 AA.com 發(fā)送了一個(gè)請(qǐng)求:a.com/act=xx。瀏覽器會(huì)默認(rèn)攜帶AA.com的Cookie
(4)AA.com接收到請(qǐng)求后,對(duì)請(qǐng)求進(jìn)行驗(yàn)證,并確認(rèn)是受害者的憑證,誤以為是受害者自己發(fā)送的請(qǐng)求
(5)AA.com以受害者的名義執(zhí)行了act=xx
(6)攻擊完成,攻擊者在受害者不知情的情況下,冒充受害者,讓AA.com執(zhí)行了自己定義的操作
三、幾種常見(jiàn)的CSRF:
(1)GET類型的CSRF
這類攻擊非常簡(jiǎn)單,只需要一個(gè)HTTP請(qǐng)求:
<img src=””>
(2)POST類型的CSRF
這種類型的 CSRF 利用起來(lái)通常使用的是一個(gè)自動(dòng)提交的表單,如:
<form action=" method=POST>
<input type="hidden" name="account" value="airing" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" /></form>
<script> document.forms[0].submit(); </script>
訪問(wèn)該頁(yè)面后,表單會(huì)自動(dòng)提交,相當(dāng)于模擬用戶完成了一次 POST 操作?梢(jiàn)這種類型的 CSRF 與第一種一樣,都是模擬請(qǐng)求,所以后端接口也不能將安全寄托在僅允許 POST 請(qǐng)求上。
(3)鏈接類型的 CSRF
鏈接類型的CSRF并不常見(jiàn),比起其他兩種用戶打開(kāi)頁(yè)面就中招的情況,這種類型需要用戶點(diǎn)擊鏈接才會(huì)觸發(fā),但本質(zhì)上與前兩種一樣。這種類型通常是在論壇發(fā)布的圖片中嵌入惡意鏈接,或者以廣告的形式誘導(dǎo)用戶中招,攻擊者通常會(huì)以比較夸張的詞語(yǔ)誘騙用戶點(diǎn)擊,例如:
<a href=" taget="_blank"> <a/>
由于之前用戶登錄了信任的網(wǎng)站A,并且保存登錄狀態(tài),只要用戶主動(dòng)訪問(wèn)這個(gè)頁(yè)面,則表示攻擊成功。
四、如何防御CSRF?
(1)驗(yàn)證HTTP Referer字段
Referer是HTTP頭中的一個(gè)字段,記錄了 HTTP 請(qǐng)求的來(lái)源地址。這種方法的顯而易見(jiàn)的好處就是簡(jiǎn)單易行,網(wǎng)站的普通開(kāi)發(fā)人員不需要操心 CSRF 的漏洞,只需要在最后給所有安全敏感的請(qǐng)求統(tǒng)一增加一個(gè)攔截器來(lái)檢查Referer 的值就可以。特別是對(duì)于當(dāng)前現(xiàn)有的系統(tǒng),不需要改變系統(tǒng)的任何已有代碼和邏輯,沒(méi)有風(fēng)險(xiǎn),非常便捷。
然而,這種方法并非萬(wàn)無(wú)一失。Referer 的值是由瀏覽器提供的,雖然 HTTP 協(xié)議上有明確的要求,但是每個(gè)瀏覽器對(duì)于 Referer 的具體實(shí)現(xiàn)可能有差別,并不能保證瀏覽器自身沒(méi)有安全漏洞。
(2)請(qǐng)求中添加token并驗(yàn)證
token就是服務(wù)端返回給客戶端類似sessionid那樣一長(zhǎng)串的類值(長(zhǎng)是為了防暴力猜解)。 CSRF依賴于瀏覽器訪問(wèn)鏈接時(shí)自動(dòng)對(duì)應(yīng)網(wǎng)站的cookie帶上,token不放cookie(一般form表單加個(gè)hidden屬性的input標(biāo)簽來(lái)存放) CSRF就沒(méi)法獲取token,這樣我們就可以通過(guò)檢測(cè)發(fā)送過(guò)來(lái)的數(shù)據(jù)包中是否有正確的token值來(lái)決定是否響應(yīng)請(qǐng)求。
這種方法要比檢查 Referer 要安全一些,token 可以在用戶登陸后產(chǎn)生并放于 session 之中,然后在每次請(qǐng)求時(shí)把 token 從 session 中拿出,與請(qǐng)求中的 token 進(jìn)行比對(duì),但這種方法的難點(diǎn)在于如何把 token 以參數(shù)的形式加入請(qǐng)求。對(duì)于 GET 請(qǐng)求,token 將附在請(qǐng)求地址之后,這樣 URL 就變成 。 而對(duì)于 POST 請(qǐng)求來(lái)說(shuō),要在 form 的最后加上 ,這樣就可以把 token 以參數(shù)的形式加入請(qǐng)求了。另外還有一個(gè)問(wèn)題就是怎么保障token本身的存儲(chǔ)安全,不要被黑客截獲。