一文带你学习跨站点请求伪造(CSRF)
一文帶你學(xué)習(xí)跨站點(diǎn)請(qǐng)求偽造(CSRF)
- 1.何為CSRF
- 2.瀏覽器的Cookie策略
- 3.P3P頭的副作用
- 4.CSRF攻擊流程
- 5.CSRF的分類(lèi)
- GET型
- POST-表單型
- POST-JSON型
- 6.CSRF的快速驗(yàn)證
- 7.CSRF的防御
- 驗(yàn)證碼
- Referer Check
- Anti CSRF Token
1.何為CSRF
CSRF的全名是Cross Site Request Forgery,翻譯成中文就是跨站點(diǎn)請(qǐng)求偽造
CSRF是一種挾制用戶在當(dāng)前已登錄的Web應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。跟跨站腳本(XSS)相比,XSS 利用的是用戶對(duì)指定網(wǎng)站的信任,CSRF 利用的是網(wǎng)站對(duì)用戶網(wǎng)頁(yè)瀏覽器的信任
例如現(xiàn)在有一個(gè)網(wǎng)站,只需要請(qǐng)求這個(gè)URL,就能夠把編號(hào)為“156713012”的博客文章刪除。
http://blog.sohu.com/manage/entry.do? m=delete&id=156713012攻擊者首先在自己的域構(gòu)造一個(gè)頁(yè)面:
其內(nèi)容為:
<img src="http://blog.sohu.com/manage/entry.do? m=delete&id=156714243" />攻擊者誘使目標(biāo)用戶訪問(wèn)這個(gè)頁(yè)面,從而執(zhí)行CSRF攻擊
該用戶看到了一張無(wú)法顯示的圖片,但是不幸的式此時(shí)該用戶的博客已經(jīng)被刪除
回顧整個(gè)攻擊過(guò)程,攻擊者僅僅誘使用戶訪問(wèn)了一個(gè)頁(yè)面,就以該用戶身份在第三方站點(diǎn)里執(zhí)行了一次操作。
這個(gè)刪除博客文章的請(qǐng)求,是攻擊者所偽造的,所以這種攻擊就叫做“跨站點(diǎn)請(qǐng)求偽造”。
CSRF漏洞的根本是:簡(jiǎn)單的身份驗(yàn)證只能保證請(qǐng)求是發(fā)自某個(gè)用戶的瀏覽器,卻不能保證請(qǐng)求本身是用戶自愿發(fā)出的💄
2.瀏覽器的Cookie策略
瀏覽器所持有的Cookie分為兩種:一種是“Session Cookie”,又稱“臨時(shí)Cookie”;另一種是“Third-party Cookie”,也稱為“本地Cookie”。
兩者的區(qū)別在于,Third-party Cookie是服務(wù)器在Set-Cookie時(shí)指定了Expire時(shí)間,只有到了Expire時(shí)間后Cookie才會(huì)失效,所以這種Cookie會(huì)保存在本地;而Session Cookie則沒(méi)有指定Expire時(shí)間,所以瀏覽器關(guān)閉后,Session Cookie就失效了。
例如:
<? php header("Set-Cookie: cookie1=123; "); header("Set-Cookie: cookie2=456; expires=Thu, 01-Jan-2030 00:00:01 GMT; ", false); ?>IE出于安全考慮,默認(rèn)禁止了瀏覽器在<img>、<iframe>、<script>、<link>等標(biāo)簽中發(fā)送第三方Cookie
攻擊者則需要精心構(gòu)造攻擊環(huán)境,比如誘使用戶在當(dāng)前瀏覽器中先訪問(wèn)目標(biāo)站點(diǎn),使得Session Cookie有效,再實(shí)施CSRF攻擊?
在當(dāng)前的主流瀏覽器中,默認(rèn)會(huì)攔截Third-party Cookie的有:IE 6、IE 7、IE 8、Safari;不會(huì)攔截的有:Firefox 2、Firefox 3、Opera、Google Chrome、Android等。
3.P3P頭的副作用
瀏覽器攔截第三方Cookie的發(fā)送,在某種程度上來(lái)說(shuō)降低了CSRF攻擊的威力。可是這一情況在“P3P頭”介入后變得復(fù)雜起來(lái)。
P3P Header是W3C制定的一項(xiàng)關(guān)于隱私的標(biāo)準(zhǔn),全稱是The Platform for Privacy Preferences。
如果網(wǎng)站返回給瀏覽器的HTTP頭中包含有P3P頭,則在某種程度上來(lái)說(shuō),將允許瀏覽器發(fā)送第三方Cookie。在IE下即使是<iframe>、<script>等標(biāo)簽也將不再攔截第三方Cookie的發(fā)送💍
在網(wǎng)站的業(yè)務(wù)中,P3P頭主要用于類(lèi)似廣告等需要跨域訪問(wèn)的頁(yè)面。
正因?yàn)镻3P頭目前在網(wǎng)站的應(yīng)用中被廣泛應(yīng)用,因此在CSRF的防御中不能依賴于瀏覽器對(duì)第三方Cookie的攔截策略,不能心存僥幸。
很多時(shí)候,如果測(cè)試CSRF時(shí)發(fā)現(xiàn)<iframe>等標(biāo)簽在IE中居然能發(fā)送Cookie,而又找不到原因,那么很可能就是因?yàn)镻3P頭在作怪。
4.CSRF攻擊流程
具體的攻擊流程如下:
5.CSRF的分類(lèi)
GET型
在web應(yīng)用中,很多接口通過(guò)GET進(jìn)行數(shù)據(jù)的請(qǐng)求和存儲(chǔ),如果未對(duì)來(lái)源進(jìn)行校驗(yàn),并且沒(méi)有token保護(hù),攻擊者可以直接通過(guò)發(fā)送含有payload的鏈接進(jìn)行誘導(dǎo)點(diǎn)擊;亦可以通過(guò)評(píng)論區(qū)或類(lèi)似功能處發(fā)布圖片,通過(guò)修改img地址的方式保存至頁(yè)面,用戶訪問(wèn)便會(huì)進(jìn)行自動(dòng)加載造成攻擊
<!-- 不論什么手段,只要能讓受害者訪問(wèn)一個(gè)鏈接即可 --> <img src="https://bank.example.com/withdraw?amount=1000&to=Bob" />POST-表單型
首先,測(cè)試時(shí),為了擴(kuò)大危害,可以嘗試將POST數(shù)據(jù)包轉(zhuǎn)換成GET數(shù)據(jù)包,后端如果采用例如@RequestMaping("/")這種同時(shí)接受POST和GET請(qǐng)求的話,就可以成功
利用起來(lái)無(wú)非也是構(gòu)造一個(gè)自動(dòng)提交的表單,然后嵌入到頁(yè)面中,誘導(dǎo)受害者訪問(wèn),受害者訪問(wèn)后會(huì)自動(dòng)提交表單發(fā)起請(qǐng)求
<form action=http://bank.example.com/csrf method=POST> <input type="text" name="amount" value="1000" /> </form> <script> document.forms[0].submit(); </script>POST-JSON型
如果我們發(fā)現(xiàn)請(qǐng)求頭中的Content-Type值是application/json,基本上就可以確定采用了前后端分離了
這種一般有4種利用手法:
- json轉(zhuǎn)param
部分網(wǎng)站可能同時(shí)支持json和表單格式,所以我們可以嘗試進(jìn)行轉(zhuǎn)換,如把 {"a":"b"} 轉(zhuǎn)換為 a=b,服務(wù)端可能也會(huì)解析
- 閉合JSON
構(gòu)造閉合語(yǔ)句,比較雞肋
- ajax發(fā)起請(qǐng)求
當(dāng)跨域影響用戶數(shù)據(jù)HTTP請(qǐng)求(如用XMLHttpRequest發(fā)送get/post)時(shí),瀏覽器會(huì)發(fā)送預(yù)檢請(qǐng)求(OPTIONS請(qǐng)求)給服務(wù)端征求支持的請(qǐng)求方法,然后根據(jù)服務(wù)端響應(yīng)允許才發(fā)送真正的請(qǐng)求。
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Access-Control-Allow-Origin: http://localhost:63342 Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1800 Access-Control-Allow-Methods: POST Access-Control-Allow-Headers: content-type,access-control-request-headers,access-control-request-method,accept,origin,x-requested-with Content-Length: 0 Date: Wed, 11 Mar 2015 05:16:31 GMT然而如果服務(wù)端對(duì)Content-Type進(jìn)行校驗(yàn),則不會(huì)響應(yīng)這個(gè)OPTIONS請(qǐng)求,從而利用失敗。但是更多的情況下服務(wù)端可能不會(huì)校驗(yàn)Content-Type,或者不會(huì)嚴(yán)格校驗(yàn)Content-Type是否為application/json,所以很多情況下這是可用的
payload:
<script>windows.onload = () => {var xhr = new XMLHttpRequest()xhr.open("POST", "http://test.example.com/csrf")xhr.setRequestHeader("Accept", "*/*")xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8")xhr.withCredentials = true // 攜帶cookiexhr.send(JSON.stringify({"a":"b"})} </script>- flash+307跳轉(zhuǎn)
flash已經(jīng)被淘汰了
6.CSRF的快速驗(yàn)證
非JSON的情況下,使用burp可以快速生成POC,也可以自己寫(xiě),反正原理都是發(fā)起請(qǐng)求即可
修改參數(shù),之后通過(guò)BP的瀏覽器進(jìn)行測(cè)試:
訪問(wèn)BP生成的網(wǎng)址:
提交,可以看到數(shù)據(jù)已經(jīng)被修改了,代表存在CSRF漏洞:
7.CSRF的防御
驗(yàn)證碼
驗(yàn)證碼被認(rèn)為是對(duì)抗CSRF攻擊最簡(jiǎn)潔而有效的防御方法。
CSRF攻擊的過(guò)程,往往是在用戶不知情的情況下構(gòu)造了網(wǎng)絡(luò)請(qǐng)求。而驗(yàn)證碼,則強(qiáng)制用戶必須與應(yīng)用進(jìn)行交互,才能完成最終請(qǐng)求。因此在通常情況下,驗(yàn)證碼能夠很好地遏制CSRF攻擊。但是驗(yàn)證碼并非萬(wàn)能。
很多時(shí)候,出于用戶體驗(yàn)考慮,網(wǎng)站不能給所有的操作都加上驗(yàn)證碼。因此,驗(yàn)證碼只能作為防御CSRF的一種輔助手段,而不能作為最主要的解決方案。
Referer Check
Referer Check在互聯(lián)網(wǎng)中最常見(jiàn)的應(yīng)用就是“防止圖片盜鏈”。同理,Referer Check也可以被用于檢查請(qǐng)求是否來(lái)自合法的“源”。
比如一個(gè)“論壇發(fā)帖”的操作,在正常情況下需要先登錄到用戶后臺(tái),或者訪問(wèn)有發(fā)帖功能的頁(yè)面。在提交“發(fā)帖”的表單時(shí),Referer的值必然是發(fā)帖表單所在的頁(yè)面。如果Referer的值不是這個(gè)頁(yè)面,甚至不是發(fā)帖網(wǎng)站的域,則極有可能是CSRF攻擊。
無(wú)法依賴于Referer Check作為防御CSRF的主要手段(黑客可能篡改Referer)。但是通過(guò)Referer Check來(lái)監(jiān)控CSRF攻擊的發(fā)生,倒是一種可行的方法💎
Anti CSRF Token
CSRF為什么能夠攻擊成功?其本質(zhì)原因是重要操作的所有參數(shù)都是可以被攻擊者猜測(cè)到的。
出于這個(gè)原因,可以想到一個(gè)解決方案:把參數(shù)加密,或者使用一些隨機(jī)數(shù),從而讓攻擊者無(wú)法猜測(cè)到參數(shù)值。
這樣,在攻擊者不知道salt的情況下,是無(wú)法構(gòu)造出這個(gè)URL的,因此也就無(wú)從發(fā)起CSRF攻擊了
比如,一個(gè)刪除操作的URL是:
http://host/path/delete? username=abc&item=123把其中的username參數(shù)改成哈希值:
http://host/path/delete? username=md5(salt+abc)&item=123但是這個(gè)方法也存在一些問(wèn)題。首先,加密或混淆后的URL將變得非常難讀,對(duì)用戶非常不友好。其次,如果加密的參數(shù)每次都改變,則某些URL將無(wú)法再被用戶收藏。最后,普通的參數(shù)如果也被加密或哈希,將會(huì)給數(shù)據(jù)分析工作帶來(lái)很大的困擾,因?yàn)閿?shù)據(jù)分析工作常常需要用到參數(shù)的明文。
因此,我們需要一個(gè)更加通用的解決方案來(lái)幫助解決這個(gè)問(wèn)題。這個(gè)方案就是使用Anti CSRF Token。
回到上面的URL中,保持原參數(shù)不變,新增一個(gè)參數(shù)Token。這個(gè)Token的值是隨機(jī)的,不可預(yù)測(cè):
http://host/path/delete? username=abc&item=123&token=[random(seed)]由于Token的存在,攻擊者無(wú)法再構(gòu)造出一個(gè)完整的URL實(shí)施CSRF攻擊。
總結(jié)
以上是生活随笔為你收集整理的一文带你学习跨站点请求伪造(CSRF)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: OKR使用经验 11-12双月
- 下一篇: 家族文化是一项很重要的文化内涵