(一)CRSF跨站請(qǐng)求偽造
CSRF(Cross-site request forgery)跨站請(qǐng)求偽造敏储,也被稱為“One Click Attack”或者Session Riding迎罗,通尘械矗縮寫(xiě)為CSRF或者XSRF辱志,是一種對(duì)網(wǎng)站的惡意利用亿胸。
CSRF是一種夾持用戶在已經(jīng)登陸的web應(yīng)用程序上執(zhí)行非本意的操作的攻擊方式粤蝎。相比于XSS赋除,CSRF是利用了系統(tǒng)對(duì)頁(yè)面瀏覽器的信任,XSS則利用了系統(tǒng)對(duì)用戶的信任保屯。
盡管聽(tīng)起來(lái)像跨站腳本(XSS)手负,但它與XSS非常不同,XSS利用站點(diǎn)內(nèi)的信任用戶姑尺,而CSRF則通過(guò)偽裝來(lái)自受信任用戶的請(qǐng)求來(lái)利用受信任的網(wǎng)站竟终。
例如:攻擊者盜用了你的身份,以你的名義發(fā)送惡意請(qǐng)求切蟋,對(duì)服務(wù)器來(lái)說(shuō)這個(gè)請(qǐng)求是完全合法的统捶,但是卻完成了攻擊者所期望的一個(gè)操作,比如以你的名義發(fā)送郵件柄粹、發(fā)消息喘鸟,盜取你的賬號(hào),添加系統(tǒng)管理員驻右,甚至于購(gòu)買商品什黑、虛擬貨幣轉(zhuǎn)賬等。 如下:其中Web A為存在CSRF漏洞的網(wǎng)站堪夭,Web B為攻擊者構(gòu)建的惡意網(wǎng)站愕把,User C為Web A網(wǎng)站的合法用戶。
(二)CRSF攻擊原理
構(gòu)成CSRF攻擊是有條件的:
1森爽、客戶端必須一個(gè)網(wǎng)站并生成cookie憑證存儲(chǔ)在瀏覽器中
2恨豁、該cookie沒(méi)有清除,客戶端又tab一個(gè)頁(yè)面進(jìn)行訪問(wèn)別的網(wǎng)站
CSRF攻擊攻擊原理及過(guò)程如下:
1. 用戶C打開(kāi)瀏覽器爬迟,訪問(wèn)受信任網(wǎng)站A橘蜜,輸入用戶名和密碼請(qǐng)求登錄網(wǎng)站A;
2.在用戶信息通過(guò)驗(yàn)證后付呕,網(wǎng)站A產(chǎn)生Cookie信息并返回給瀏覽器计福,此時(shí)用戶登錄網(wǎng)站A成功,可以正常發(fā)送請(qǐng)求到網(wǎng)站A徽职;
3. 用戶未退出網(wǎng)站A之前象颖,在同一瀏覽器中,打開(kāi)一個(gè)TAB頁(yè)訪問(wèn)網(wǎng)站B活箕;
4. 網(wǎng)站B接收到用戶請(qǐng)求后力麸,返回一些攻擊性代碼可款,并發(fā)出一個(gè)請(qǐng)求要求訪問(wèn)第三方站點(diǎn)A;
5. 瀏覽器在接收到這些攻擊性代碼后克蚂,根據(jù)網(wǎng)站B的請(qǐng)求闺鲸,在用戶不知情的情況下攜帶Cookie信息,向網(wǎng)站A發(fā)出請(qǐng)求埃叭。網(wǎng)站A并不知道該請(qǐng)求其實(shí)是由B發(fā)起的摸恍,所以會(huì)根據(jù)用戶C的Cookie信息以C的權(quán)限處理該請(qǐng)求,導(dǎo)致來(lái)自網(wǎng)站B的惡意代碼被執(zhí)行赤屋。
(三)CRSF攻擊實(shí)例
受害者 Bob 在銀行有一筆存款立镶,通過(guò)對(duì)銀行的網(wǎng)站發(fā)送請(qǐng)求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2 可以使 Bob 把 1000000 的存款轉(zhuǎn)到 bob2 的賬號(hào)下。通常情況下类早,該請(qǐng)求發(fā)送到網(wǎng)站后媚媒,服務(wù)器會(huì)先驗(yàn)證該請(qǐng)求是否來(lái)自一個(gè)合法的 session,并且該 session 的用戶 Bob 已經(jīng)成功登陸涩僻。
黑客 Mallory 自己在該銀行也有賬戶缭召,他知道上文中的 URL 可以把錢進(jìn)行轉(zhuǎn)帳操作。Mallory 可以自己發(fā)送一個(gè)請(qǐng)求給銀行:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory逆日。但是這個(gè)請(qǐng)求來(lái)自 Mallory 而非 Bob嵌巷,他不能通過(guò)安全認(rèn)證,因此該請(qǐng)求不會(huì)起作用室抽。
這時(shí)搪哪,Mallory 想到使用 CSRF 的攻擊方式,他先自己做一個(gè)網(wǎng)站坪圾,在網(wǎng)站中放入如下代碼: src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”晓折,并且通過(guò)廣告等誘使 Bob 來(lái)訪問(wèn)他的網(wǎng)站。當(dāng) Bob 訪問(wèn)該網(wǎng)站時(shí)神年,上述 url 就會(huì)從 Bob 的瀏覽器發(fā)向銀行已维,而這個(gè)請(qǐng)求會(huì)附帶 Bob 瀏覽器中的 cookie 一起發(fā)向銀行服務(wù)器行嗤。大多數(shù)情況下已日,該請(qǐng)求會(huì)失敗,因?yàn)樗?Bob 的認(rèn)證信息栅屏。但是飘千,如果 Bob 當(dāng)時(shí)恰巧剛訪問(wèn)他的銀行后不久,他的瀏覽器與銀行網(wǎng)站之間的 session 尚未過(guò)期栈雳,瀏覽器的 cookie 之中含有 Bob 的認(rèn)證信息护奈。這時(shí),悲劇發(fā)生了哥纫,這個(gè) url 請(qǐng)求就會(huì)得到響應(yīng)霉旗,錢將從 Bob 的賬號(hào)轉(zhuǎn)移到 Mallory 的賬號(hào),而 Bob 當(dāng)時(shí)毫不知情。等以后 Bob 發(fā)現(xiàn)賬戶錢少了厌秒,即使他去銀行查詢?nèi)罩径敛穑仓荒馨l(fā)現(xiàn)確實(shí)有一個(gè)來(lái)自于他本人的合法請(qǐng)求轉(zhuǎn)移了資金,沒(méi)有任何被攻擊的痕跡鸵闪。而 Mallory 則可以拿到錢后逍遙法外檐晕。
(四)CRSF攻擊檢測(cè)
檢測(cè)CSRF漏洞是一項(xiàng)比較繁瑣的工作,最簡(jiǎn)單的方法就是抓取一個(gè)正常請(qǐng)求的數(shù)據(jù)包蚌讼,去掉Referer字段后再重新提交辟灰,如果該提交還有效,那么基本上可以確定存在CSRF漏洞篡石。
隨著對(duì)CSRF漏洞研究的不斷深入芥喇,不斷涌現(xiàn)出一些專門(mén)針對(duì)CSRF漏洞進(jìn)行檢測(cè)的工具,如CSRFTester凰萨,CSRF Request Builder等乃坤。
以CSRFTester工具為例,CSRF漏洞檢測(cè)工具的測(cè)試原理如下:使用CSRFTester進(jìn)行測(cè)試時(shí)沟蔑,首先需要抓取我們?cè)跒g覽器中訪問(wèn)過(guò)的所有鏈接以及所有的表單等信息湿诊,然后通過(guò)在CSRFTester中修改相應(yīng)的表單等信息,重新提交瘦材,這相當(dāng)于一次偽造客戶端請(qǐng)求厅须。如果修改后的測(cè)試請(qǐng)求成功被網(wǎng)站服務(wù)器接受,則說(shuō)明存在CSRF漏洞食棕,當(dāng)然此款工具也可以被用來(lái)進(jìn)行CSRF攻擊朗和。
(五)CRSF攻擊防御
1、重要數(shù)據(jù)交互采用POST進(jìn)行接收簿晓,當(dāng)然是用POST也不是萬(wàn)能的眶拉,偽造一個(gè)form表單即可破解
惡意攻擊者根據(jù)游戲虛擬幣轉(zhuǎn)賬表單進(jìn)行偽造了一份一模一樣的轉(zhuǎn)賬表單,并且嵌入到iframe中
嵌套頁(yè)面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>攻擊者主機(jī)頁(yè)面</title>
<script type="text/javascript">
function csrf()
{
window.frames['steal'].document.forms[0].submit();
}
</script>
</head>
<body onload="csrf()">
<iframe name="steal" display="none" src="./xsrf.html">
</iframe>
</body>
</html>
xsrf.html
<!DOCTYPE html>
<html>
<head>
<title>csrf</title>
</head>
<body>
<form display="none" action="http://www.game.com/Transfer.php" method="post" >
<input type="hidden" name="toUserID" value="20">
<input type="hidden" name="vMoney" value="1000">
</form>
</body>
</html>
2憔儿、使用驗(yàn)證碼忆植,只要是涉及到數(shù)據(jù)交互就先進(jìn)行驗(yàn)證碼驗(yàn)證,這個(gè)方法可以完全解決CSRF谒臼。但是出于用戶體驗(yàn)考慮朝刊,網(wǎng)站不能給所有的操作都加上驗(yàn)證碼。因此驗(yàn)證碼只能作為一種輔助手段,不能作為主要解決方案。
3纸厉、驗(yàn)證HTTP Referer字段,該字段記錄了此次HTTP請(qǐng)求的來(lái)源地址咙鞍,最常見(jiàn)的應(yīng)用是圖片防盜鏈房官。PHP中可以采用APache URL重寫(xiě)規(guī)則進(jìn)行防御,可參考:http://www.cnblogs.com/phpstudy2015-6/p/6715892.html
4续滋、為每個(gè)表單添加令牌token并驗(yàn)證
使用cookie或者session進(jìn)行構(gòu)造易阳。
CSRF攻擊之所以能夠成功,是因?yàn)楣粽呖梢詡卧煊脩舻恼?qǐng)求吃粒,該請(qǐng)求中所有的用戶驗(yàn)證信息都存在于Cookie中潦俺,因此攻擊者可以在不知道這些驗(yàn)證信息的情況下直接利用用戶自己的Cookie來(lái)通過(guò)安全驗(yàn)證。由此可知徐勃,抵御CSRF攻擊的關(guān)鍵在于:在請(qǐng)求中放入攻擊者所不能偽造的信息事示,并且該信息不存在于Cookie之中。
鑒于此僻肖,我們將為每一個(gè)表單生成一個(gè)隨機(jī)數(shù)秘鑰肖爵,并在服務(wù)器端建立一個(gè)攔截器來(lái)驗(yàn)證這個(gè)token,如果請(qǐng)求中沒(méi)有token或者token內(nèi)容不正確臀脏,則認(rèn)為可能是CSRF攻擊而拒絕該請(qǐng)求劝堪。
由于這個(gè)token是隨機(jī)不可預(yù)測(cè)的并且是隱藏看不見(jiàn)的,因此惡意攻擊者就不能夠偽造這個(gè)表單進(jìn)行CSRF攻擊了揉稚。
要求:
1秒啦、要確保同一頁(yè)面中每個(gè)表單都含有自己唯一的令牌
2、驗(yàn)證后需要?jiǎng)h除相應(yīng)的隨機(jī)數(shù)
目前防御 CSRF 攻擊主要有三種策略:驗(yàn)證 HTTP Referer 字段搀玖;在請(qǐng)求地址中添加 token 并驗(yàn)證余境;在 HTTP 頭中自定義屬性并驗(yàn)證。
(1)驗(yàn)證 HTTP Referer 字段
根據(jù) HTTP 協(xié)議灌诅,在 HTTP 頭中有一個(gè)字段叫 Referer芳来,它記錄了該 HTTP 請(qǐng)求的來(lái)源地址。在通常情況下猜拾,訪問(wèn)一個(gè)安全受限頁(yè)面的請(qǐng)求來(lái)自于同一個(gè)網(wǎng)站即舌,比如需要訪問(wèn) http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,用戶必須先登陸 bank.example挎袜,然后通過(guò)點(diǎn)擊頁(yè)面上的按鈕來(lái)觸發(fā)轉(zhuǎn)賬事件顽聂。這時(shí),該轉(zhuǎn)帳請(qǐng)求的 Referer 值就會(huì)是轉(zhuǎn)賬按鈕所在的頁(yè)面的 URL宋雏,通常是以 bank.example 域名開(kāi)頭的地址芜飘。而如果黑客要對(duì)銀行網(wǎng)站實(shí)施 CSRF 攻擊务豺,他只能在他自己的網(wǎng)站構(gòu)造請(qǐng)求磨总,當(dāng)用戶通過(guò)黑客的網(wǎng)站發(fā)送請(qǐng)求到銀行時(shí),該請(qǐng)求的 Referer 是指向黑客自己的網(wǎng)站笼沥。因此蚪燕,要防御 CSRF 攻擊娶牌,銀行網(wǎng)站只需要對(duì)于每一個(gè)轉(zhuǎn)賬請(qǐng)求驗(yàn)證其 Referer 值,如果是以 bank.example 開(kāi)頭的域名馆纳,則說(shuō)明該請(qǐng)求是來(lái)自銀行網(wǎng)站自己的請(qǐng)求诗良,是合法的。如果 Referer 是其他網(wǎng)站的話鲁驶,則有可能是黑客的 CSRF 攻擊鉴裹,拒絕該請(qǐng)求。
這種方法的顯而易見(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)脆霎,不需要改變當(dāng)前系統(tǒng)的任何已有代碼和邏輯总处,沒(méi)有風(fēng)險(xiǎn),非常便捷睛蛛。
然而鹦马,這種方法并非萬(wàn)無(wú)一失。Referer 的值是由瀏覽器提供的忆肾,雖然 HTTP 協(xié)議上有明確的要求荸频,但是每個(gè)瀏覽器對(duì)于 Referer 的具體實(shí)現(xiàn)可能有差別,并不能保證瀏覽器自身沒(méi)有安全漏洞客冈。使用驗(yàn)證 Referer 值的方法试溯,就是把安全性都依賴于第三方(即瀏覽器)來(lái)保障,從理論上來(lái)講郊酒,這樣并不安全遇绞。事實(shí)上,對(duì)于某些瀏覽器燎窘,比如 IE6 或 FF2摹闽,目前已經(jīng)有一些方法可以篡改 Referer 值。如果 bank.example 網(wǎng)站支持 IE6 瀏覽器褐健,黑客完全可以把用戶瀏覽器的 Referer 值設(shè)為以 bank.example 域名開(kāi)頭的地址付鹿,這樣就可以通過(guò)驗(yàn)證,從而進(jìn)行 CSRF 攻擊蚜迅。
即便是使用最新的瀏覽器舵匾,黑客無(wú)法篡改 Referer 值,這種方法仍然有問(wèn)題谁不。因?yàn)?Referer 值會(huì)記錄下用戶的訪問(wèn)來(lái)源坐梯,有些用戶認(rèn)為這樣會(huì)侵犯到他們自己的隱私權(quán),特別是有些組織擔(dān)心 Referer 值會(huì)把組織內(nèi)網(wǎng)中的某些信息泄露到外網(wǎng)中刹帕。因此吵血,用戶自己可以設(shè)置瀏覽器使其在發(fā)送請(qǐng)求時(shí)不再提供 Referer谎替。當(dāng)他們正常訪問(wèn)銀行網(wǎng)站時(shí),網(wǎng)站會(huì)因?yàn)檎?qǐng)求沒(méi)有 Referer 值而認(rèn)為是 CSRF 攻擊蹋辅,拒絕合法用戶的訪問(wèn)钱贯。
(2)在請(qǐng)求地址中添加 token 并驗(yàn)證
CSRF 攻擊之所以能夠成功,是因?yàn)楹诳涂梢酝耆珎卧煊脩舻恼?qǐng)求侦另,該請(qǐng)求中所有的用戶驗(yàn)證信息都是存在于 cookie 中秩命,因此黑客可以在不知道這些驗(yàn)證信息的情況下直接利用用戶自己的 cookie 來(lái)通過(guò)安全驗(yàn)證。要抵御 CSRF褒傅,關(guān)鍵在于在請(qǐng)求中放入黑客所不能偽造的信息硫麻,并且該信息不存在于 cookie 之中》浚可以在 HTTP 請(qǐng)求中以參數(shù)的形式加入一個(gè)隨機(jī)產(chǎn)生的 token拿愧,并在服務(wù)器端建立一個(gè)攔截器來(lái)驗(yàn)證這個(gè) token,如果請(qǐng)求中沒(méi)有 token 或者 token 內(nèi)容不正確碌尔,則認(rèn)為可能是 CSRF 攻擊而拒絕該請(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 就變成 http://url?csrftoken=tokenvalue募书。 而對(duì)于 POST 請(qǐng)求來(lái)說(shuō)绪囱,要在 form 的最后加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>,這樣就把 token 以參數(shù)的形式加入請(qǐng)求了莹捡。但是鬼吵,在一個(gè)網(wǎng)站中,可以接受請(qǐng)求的地方非常多篮赢,要對(duì)于每一個(gè)請(qǐng)求都加上 token 是很麻煩的齿椅,并且很容易漏掉,通常使用的方法就是在每次頁(yè)面加載時(shí)启泣,使用 javascript 遍歷整個(gè) dom 樹(shù)涣脚,對(duì)于 dom 中所有的 a 和 form 標(biāo)簽后加入 token。這樣可以解決大部分的請(qǐng)求寥茫,但是對(duì)于在頁(yè)面加載之后動(dòng)態(tài)生成的 html 代碼遣蚀,這種方法就沒(méi)有作用,還需要程序員在編碼時(shí)手動(dòng)添加 token。
該方法還有一個(gè)缺點(diǎn)是難以保證 token 本身的安全妙同。特別是在一些論壇之類支持用戶自己發(fā)表內(nèi)容的網(wǎng)站射富,黑客可以在上面發(fā)布自己個(gè)人網(wǎng)站的地址膝迎。由于系統(tǒng)也會(huì)在這個(gè)地址后面加上 token粥帚,黑客可以在自己的網(wǎng)站上得到這個(gè) token,并馬上就可以發(fā)動(dòng) CSRF 攻擊限次。為了避免這一點(diǎn)芒涡,系統(tǒng)可以在添加 token 的時(shí)候增加一個(gè)判斷,如果這個(gè)鏈接是鏈到自己本站的卖漫,就在后面添加 token费尽,如果是通向外網(wǎng)則不加。不過(guò)羊始,即使這個(gè) csrftoken 不以參數(shù)的形式附加在請(qǐng)求之中旱幼,黑客的網(wǎng)站也同樣可以通過(guò) Referer 來(lái)得到這個(gè) token 值以發(fā)動(dòng) CSRF 攻擊。這也是一些用戶喜歡手動(dòng)關(guān)閉瀏覽器 Referer 功能的原因突委。
該方法套路:
用戶訪問(wèn)某個(gè)表單頁(yè)面柏卤。
服務(wù)端生成一個(gè)Token,放在用戶的Session中匀油,或者瀏覽器的Cookie中缘缚。
在頁(yè)面表單附帶上Token參數(shù)。
用戶提交請(qǐng)求后敌蚜, 服務(wù)端驗(yàn)證表單中的Token是否與用戶Session(或Cookies)中的Token一致桥滨,一致為合法請(qǐng)求,不是則非法請(qǐng)求弛车。
(3)在 HTTP 頭中自定義屬性并驗(yàn)證
這種方法也是使用 token 并進(jìn)行驗(yàn)證齐媒,和上一種方法不同的是,這里并不是把 token 以參數(shù)的形式置于 HTTP 請(qǐng)求之中纷跛,而是把它放到 HTTP 頭中自定義的屬性里里初。通過(guò) XMLHttpRequest 這個(gè)類,可以一次性給所有該類請(qǐng)求加上 csrftoken 這個(gè) HTTP 頭屬性忽舟,并把 token 值放入其中双妨。這樣解決了上種方法在請(qǐng)求中加入 token 的不便,同時(shí)叮阅,通過(guò) XMLHttpRequest 請(qǐng)求的地址不會(huì)被記錄到瀏覽器的地址欄刁品,也不用擔(dān)心 token 會(huì)透過(guò) Referer 泄露到其他網(wǎng)站中去。
然而這種方法的局限性非常大浩姥。XMLHttpRequest 請(qǐng)求通常用于 Ajax 方法中對(duì)于頁(yè)面局部的異步刷新挑随,并非所有的請(qǐng)求都適合用這個(gè)類來(lái)發(fā)起,而且通過(guò)該類請(qǐng)求得到的頁(yè)面不能被瀏覽器所記錄下勒叠,從而進(jìn)行前進(jìn)兜挨,后退膏孟,刷新,收藏等操作拌汇,給用戶帶來(lái)不便柒桑。另外,對(duì)于沒(méi)有進(jìn)行 CSRF 防護(hù)的遺留系統(tǒng)來(lái)說(shuō)噪舀,要采用這種方法來(lái)進(jìn)行防護(hù)魁淳,要把所有請(qǐng)求都改為 XMLHttpRequest 請(qǐng)求,這樣幾乎是要重寫(xiě)整個(gè)網(wǎng)站与倡,這代價(jià)無(wú)疑是不能接受的界逛。
參考:這兩個(gè)我都覺(jué)得很好,其實(shí)我自己也不是很懂纺座,沒(méi)有實(shí)踐息拜,只是了解,以后會(huì)更加深入了解的净响。
參考: