跨站請(qǐng)求偽造(CSRF)的是 Web 應(yīng)用程序一種常見的漏洞,其攻擊特性是危害性大但非常隱蔽,尤其是在大量 Web 2.0 技術(shù)的應(yīng)用的背景下,CSRF 攻擊完全可以在用戶法毫無察覺的情況下發(fā)起攻擊。國(guó)際上并未對(duì) CSRF 攻擊做出一個(gè)明確的定義,同時(shí),攻擊的發(fā)起手段方式繁多,下文會(huì)做詳細(xì)介紹。可以解釋的是發(fā)起的目標(biāo)都是通過偽造一個(gè)用戶請(qǐng)求,該請(qǐng)求不是用戶想發(fā)出去的請(qǐng)求,而對(duì)服務(wù)器或服務(wù)來說這個(gè)請(qǐng)求是完全合法的一個(gè)請(qǐng)求,但是卻完成了一個(gè)攻擊者所期望的操作,比如添加一個(gè)用戶到管理者的群組中,或?qū)⒁粋€(gè)用戶的現(xiàn)金轉(zhuǎn)到另外的一個(gè)帳戶中。通常開發(fā)人員對(duì) CSRF 攻擊的理解是有誤區(qū)的,分為以下幾方面,第一是如何攻擊的,第二是危害到底在那里,第三是如何防范就才是一個(gè)完整的解決方案。本文就是要對(duì)這些基本的問題做一個(gè)詳細(xì)的闡述,并且給出檢測(cè)的有效方法。
大部分網(wǎng)站往往對(duì)腳本注入有嚴(yán)格的防范,但是對(duì) CSRF 的防范做的就差很多。
實(shí)例 1:假設(shè)某網(wǎng)站高級(jí)會(huì)員會(huì)享有某些特殊權(quán)限。而當(dāng)一個(gè)普通用戶付款完畢就可以讓管理員將自己升級(jí)為高級(jí)會(huì)員。假設(shè)管理員將一個(gè)普通用戶升級(jí)為高級(jí)會(huì)員的請(qǐng)求是:
http://www.mysite.com/promoteUser.jsp?username=aaaaa
我們?cè)偌僭O(shè)普通用戶有在網(wǎng)站某個(gè)論壇發(fā)表話題的權(quán)限,這樣一個(gè)普通用戶可以將這個(gè) URL 發(fā)表在某些話題之中,然后用我們稱為社會(huì)工程學(xué)的方法引誘網(wǎng)站管理員點(diǎn)擊這個(gè)鏈接。當(dāng)管理員點(diǎn)擊這個(gè)鏈接時(shí),這個(gè)請(qǐng)求就會(huì)從瀏覽器發(fā)送到后臺(tái)服務(wù)器,從而完成身份的升級(jí)。當(dāng)然,在實(shí)際攻擊過程中,有很多手段使得讓管理員不點(diǎn)擊也能發(fā)送這樣的請(qǐng)求,比如將這個(gè) URL 設(shè)置為某個(gè)圖片的源。
實(shí)例 2:以一個(gè)二手跳蚤市場(chǎng)為例子,比如某商業(yè)交易網(wǎng)站注冊(cè)用戶 Hacker01 和 Customer01。Hacker01 在上交易頻道擺上 1 輛 9 成新的寶馬,投標(biāo)價(jià)格是 20000$,另外再擺上另外一量廢舊車型標(biāo)價(jià) 1000$,然而網(wǎng)站是允許加載圖片顯示車的狀況的。所以寶馬車主可以上載一個(gè)自己的圖片,廢舊車主也可以上載一個(gè)自己的圖片。
寶馬圖片 url:http://myrepository/BMW.jpg car id 100000001
廢舊車圖片 url:http://myrepository/oldCar.jpg car id 100000002
而該拍賣網(wǎng)站是通過投標(biāo)決定車的最終價(jià)格,假設(shè)是競(jìng)買者參加競(jìng)買寶馬的時(shí)候點(diǎn)擊購買按鈕瀏覽器是通過發(fā)一個(gè) GET 請(qǐng)求到 http://e-bussiness-car/bid?value=20000$&carid=100000001
來提交自己的競(jìng)標(biāo)價(jià)格。那么 Hacker01 則可以把廢舊車圖片修改為 http://e-bussiness-car/bid?value=20000$&carid=100000001
(或者其他的 value 參數(shù)的數(shù)值)。
這時(shí)候的情況是:Customer01 訪問寶馬能看見正確的圖片,并且沒有任何問題。而訪問廢舊車發(fā)現(xiàn)圖片是一個(gè)無法看到的圖片,但當(dāng) Customer01 瀏覽舊車圖片的時(shí)候,瀏覽器已經(jīng)向?qū)汃R車發(fā)送了一個(gè)競(jìng)標(biāo)請(qǐng)求。這樣在用戶的控制之外發(fā)出了一個(gè)合法的請(qǐng)求,并且被服務(wù)器接收。Hack01 可以在 Customer01 不知覺的情況下將自己的寶馬車賣出。通過此例可以發(fā)現(xiàn) CSRF 有著非常嚴(yán)重的危害性。
HTTP 協(xié)議中定義了,GET/POST/PUT/DELETE 四種基本操作方法如圖 1 標(biāo)記-1 所示 GET/POST 是所有網(wǎng)站或服務(wù)器必須使用的操作方法,而 PUT/DELETE 功能強(qiáng)大,但是在以往的應(yīng)用中并沒有被廣泛的使用,直到 Web 2.0 的出現(xiàn),Ajax 的引用導(dǎo)致 PUT/DELETE 在 REST 框架下被發(fā)揚(yáng)光大,大量使用,也使 CSRF 的攻擊手段中多了一種攻擊方式。本文以常用的 GET/POST 為實(shí)例,這兩者是被瀏覽器用作與服務(wù)起進(jìn)行數(shù)據(jù)交互的主要手段,并包含 Ajax 框架下的攻擊介紹。
CSRF 攻擊的方法多種多樣,而對(duì)這些攻擊方法的認(rèn)識(shí)將更有助于去檢查或在產(chǎn)品設(shè)計(jì)中加入對(duì) CSRF 攻擊的防范使整個(gè)產(chǎn)品的開發(fā)的代價(jià)更小。按照攻擊的方式來看,分為顯式攻擊和隱式攻擊。顯示攻擊對(duì)用戶來說是可以察覺的,例如通過各種方法向受害者發(fā)送鏈接,而隱式攻擊則很難察覺,往往是訪問了一個(gè)有漏洞的頁面,或者一個(gè)惡意的頁面,使用頻率更多的則是隱性攻擊,因?yàn)槠涓邆淇刹僮餍?。下邊介紹到的攻擊方法都可以采取隱式攻擊方法。要注意的是,用戶網(wǎng)站是否存在腳本注入的漏洞,并不影響 CSRF 攻擊,通過使用第 3 方存在安全隱患的網(wǎng)站一樣可以完成 CSRF 攻擊。
對(duì)圖 1 的基本解釋,標(biāo)記-1 是合法用戶對(duì)用戶網(wǎng)站的訪問,執(zhí)行合法有效的操作;標(biāo)記-2 是通過郵件系統(tǒng)對(duì)用戶發(fā)動(dòng)攻擊;標(biāo)記 3 是利用 Web 的網(wǎng)站,包括用戶的操作網(wǎng)站,普通網(wǎng)站,以及黑客網(wǎng)站,標(biāo)記-4、5、6 指的是有害用戶(標(biāo)記-3)利用的 3 種方式來攻擊受害用戶。
GET 請(qǐng)求使用的頻率最高,隱式的 GET 請(qǐng)求,例如 <img> <script><frame><iframe>
,在頁面中引入上述頁面元素,并且設(shè)置 SRC 屬性就能在用戶未知的情況下發(fā)出一個(gè) GET 請(qǐng)求到想去攻擊的網(wǎng)站。
以 IMG 標(biāo)簽為例,攻擊者可以通過在圖 1 中的標(biāo)記-5、標(biāo)記-6、標(biāo)記-2、標(biāo)記-4 的途徑發(fā)起攻擊。這種攻擊的特征是無明顯提示,但是已經(jīng)發(fā)出一個(gè)具有完整合法的用戶請(qǐng)求。
<img src=http://UserSite/admin/deletepage?id=74NBCDSEFG/>
對(duì)于一個(gè)大量采用 GET 請(qǐng)求的網(wǎng)站,隱式的通過 http 標(biāo)簽發(fā)出一個(gè) GET 請(qǐng)求將是致命的。
具體的可執(zhí)行情形描述將在如何檢測(cè)部分給出。
對(duì) CSRF 有一種理解是把 GET 改為 POST 請(qǐng)求就認(rèn)為是可以防止被攻擊實(shí)際上是一種錯(cuò)誤的理解,通過使用 <iframe> 一樣可以完成一個(gè)隱式的 CSRF 攻擊,具體腳本寫法如下。
<script>function post(url, fields) { var p = document.createElement('form'); p.action = url; p.innerHTML = fields; p.target = '_self'; p.enctype = 'multipart/form-data'; p.method = 'post'; document.body.appendChild(p); p.submit();}function csrf_hack() { var fields; var csrf="<addMember dnName="CN=manager 9/OU=Managers/OU=Users/O=QDSVT/DC=CN/DC=IBM/DC=COM" accessLevel="Author" isPerson="1" isLocal="0"/>"; fields += "<input type='' name='action' value='"+csrf+"'>"; unescape(fields); post('http://usersite:80/dm/services/DocumentService?do401=true',fields); alert("csrf_end");} csrf_hack(); alert('end')</script>
<IFRAME src=./frame1.html width=0 height=0></IFRAME>
這段代碼通過腳本構(gòu)造一個(gè)表單提交,通過 IFRAME 加載頁面自動(dòng)執(zhí)行本例,IFRAME 寬高屬性設(shè)置成零的目的是為了達(dá)到隱式攻擊的效果,JAVASCRIPT 只對(duì)窗口的大小有不成文的規(guī)范,寬高不能小于 50 像素點(diǎn),但是對(duì) iframe 并沒有要求,這為隱式的跨域 Post 攻擊提供了一個(gè)量好的途徑。寫成腳本的形式并不是說明只要被檢測(cè)的站點(diǎn)沒有腳本注入就沒有任何問題,POST 隱式攻擊方式一樣可以通過第 3 方,如圖 1,4,5,6 攻擊路徑都適合本例的使用。
Web 2.0 技術(shù)因其能大幅度提升用戶的體驗(yàn),已經(jīng)被非常廣泛的使用,并且 Web 2.0 技術(shù)對(duì)跨站請(qǐng)求的提交有嚴(yán)格的檢查,所以一般不用擔(dān)心來自第三方的 xmlhttp 發(fā)出的 CSRF 攻擊。Web 2.0 技術(shù)如果在本站點(diǎn)存在腳本注入漏洞,將會(huì)產(chǎn)生嚴(yán)重的 CSRF 攻擊問題;另外一條攻擊路徑則是通過郵件系統(tǒng),向受害用戶發(fā)送帶有 xmlhttp 請(qǐng)求的腳本文件,是否產(chǎn)生危害取決于用戶是否執(zhí)行該文件,危害性明顯低于前兩種。
對(duì)于發(fā)郵件,或者網(wǎng)站上傳的文件發(fā)起攻擊的案例是由 IE 的特性造成,由于 IE 允許從本地域 (local domain) 對(duì)任意域發(fā)送,一個(gè)包含 Web 2.0 代碼的例子就能使 IE 完成成一次離線狀態(tài)的攻擊,IE 允許通過對(duì)策略的修改以達(dá)到嚴(yán)格的安全配置,從而禁止對(duì)同域內(nèi)容的訪問。
以下是通常使用的對(duì) Web 2.0 類型的跨站漏洞的攻擊代碼。
<script>alert('start delete');var payload="<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header> <serviceVersion>8.0.0 </serviceVersion></soap:Header><soap:Body><deleteDocument xmlns="http://webservices.clb.content.ibm.com"> <path>/@Pcsrftestplace/@RMain.nsf/@F/@DE44FD4FF0956D07648257570002C42DA </path> </deleteDocument></soap:Body></soap:Envelope>";alert(message);var client = new XMLHttpRequest(); client.open("POST", "http://usercite.com /files/form/api/collections/ 2d0f6188-8872-4722-8922-3a3c842aa443/entry?format=xml "); client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); client.setRequestHeader("x-method-override","DELETE"); client.setRequestHeader("x-requested-with","XMLHttpRequest"); (you can customized the header if you need) client.send("");</script> <html>
登陸式的跨站請(qǐng)求偽造是一種較新的攻擊方式,讓用戶錯(cuò)誤的以為是用自己的帳戶密碼登陸,實(shí)際上是登錄到一個(gè) Hacker 的賬戶。這種攻擊方式的最顯著的特征是,Hacker 可以監(jiān)聽到用戶的實(shí)際操作,通過查詢歷史記錄可以知道用戶做了那些操作,如果是在商業(yè)網(wǎng)站則會(huì)在歷史記錄中留下信用卡號(hào),如果是在個(gè)人信息相關(guān)系統(tǒng)則會(huì)留下用戶的隱私操作。
APPSCAN 是 IBM 收購 WatchFire 之后獲得一款強(qiáng)大的網(wǎng)絡(luò)安全的檢測(cè)工具,目前屬于 Rational 產(chǎn)品線,功能集中在網(wǎng)絡(luò)應(yīng)用產(chǎn)品的檢測(cè)防范上,分靜態(tài)與動(dòng)態(tài)兩種不同的功能,覆蓋代碼與產(chǎn)品的兩端檢測(cè)需求。
APPSCAN 自從 7.7 的版本以后加入對(duì) CSRF 的防范,基本原理是通過對(duì)同一個(gè)需要檢測(cè)的 URL 或者 SERVICE 按照順序發(fā)出兩次請(qǐng)求,發(fā)送兩次請(qǐng)求之間會(huì)做一次退出登錄狀態(tài)的操作,如果一個(gè)對(duì) CSRF 已經(jīng)進(jìn)行防范的網(wǎng)站是會(huì)發(fā)送回兩個(gè)不同的回應(yīng)內(nèi)容。實(shí)例的說明如下。
請(qǐng)求 1
GET/POST http://myproduct.com/services?action=remove&id=10002Headers ….. ….. Content: ……
返回內(nèi)容 1
Response 200Headers …. …..Content:…..
請(qǐng)求 2
GET/POST http://myproduct.com/services?action=remove&id=10002Headers ….. ….. Content: ……
返回內(nèi)容 2
Response 200Headers …. …..Content:…..
返回內(nèi)容 1 和返回內(nèi)容 2 如果是完全一致的則可以認(rèn)為是有問題的,反之則可以認(rèn)為是沒有問題??此坪?jiǎn)單的原理,在實(shí)際操作中有個(gè)很繁瑣的邏輯問題,比如請(qǐng)求 1 是一個(gè)刪除動(dòng)作,那么如何去構(gòu)造一個(gè)請(qǐng)求 2,并且獲得一個(gè)一致的結(jié)果呢?解決的辦法是,要先做一個(gè)操作 1,然后再創(chuàng)建一個(gè)同樣的 1,再做操作 2。
從上述的簡(jiǎn)單例子就可以發(fā)現(xiàn)有效監(jiān)測(cè) CSRF 是一個(gè)較為繁瑣的過程。AppScan 的檢測(cè)前提就是對(duì)目標(biāo)資源的操作在不同的一個(gè) Session 中返回的內(nèi)容肯定是應(yīng)該不一樣的。
這里要注意的問題是誤報(bào),Web 應(yīng)用程序操作大多都是對(duì)一個(gè)固定的 URL 的請(qǐng)求,包含一些資源文件,以及一些功能性的請(qǐng)求。對(duì)于資源文件的操作,很多情況下都是一個(gè)靜態(tài)的請(qǐng)求,在未使用 PUT/DELETE 的應(yīng)用程序,是無需對(duì) GET 請(qǐng)求進(jìn)行 CSRF 測(cè)試,在這種情況下是不存在 CSRF 漏洞的。而如果使用了 Ajax 框架的應(yīng)用程序如果存在 DELETE/PUT 操作則需注意很可能出現(xiàn)嚴(yán)重的 CSRF 問題。未使用 Ajax 的產(chǎn)品則集中在 GET/POST 請(qǐng)求,需要注意的是 GET/POST 請(qǐng)求對(duì) CSRF 來說是同樣具有可操作性的,對(duì)產(chǎn)品的危害性是一致的。
對(duì) CSRF 測(cè)試的兩個(gè)主要方向是路徑覆蓋測(cè)試,和精確測(cè)試。之所以是要做如此分類的原因是一個(gè)產(chǎn)品有大量的 URL 如果一一測(cè)試需要大量的時(shí)間精力,覆蓋測(cè)試是由工具去完成的是為了保證覆蓋到產(chǎn)品的各個(gè)路徑,有些產(chǎn)品實(shí)際上已經(jīng)對(duì) CSRF 有很深的認(rèn)識(shí),在這種情況下大多數(shù)資源已經(jīng)被很好的保護(hù)起來,沒有 CSRF 的問題,這時(shí)候一個(gè)對(duì)全路徑的測(cè)試就是很必要的。
精確測(cè)試是由人來完成的通過分析產(chǎn)品功能和開發(fā)人員的溝通,閱讀設(shè)計(jì)文檔來完成的。為何要做精確測(cè)試的原因是,所有 Web 應(yīng)用程序非常關(guān)注的問題之一就是產(chǎn)品的性能,而對(duì)所有請(qǐng)求都做 CSRF 防范的話就比如在一個(gè)高速公路上設(shè)置一個(gè)人工收費(fèi)站一樣會(huì)大大影響性能,一個(gè)好的 Web 應(yīng)用在對(duì) CSRF 防范是有針對(duì)性的,對(duì)一個(gè)沒有 CSRF 保護(hù)的產(chǎn)品,一個(gè)良好的 CSRF 保護(hù)開端可以是由精確測(cè)試的結(jié)果為發(fā)起的。通過對(duì)固定功能的檢測(cè),以及對(duì)設(shè)計(jì)文檔的了解,基本就可以斷定產(chǎn)品是否做了 CSRF 保護(hù)。
一個(gè)正常的使用 Appscan 來檢測(cè) CSRF 的流程如圖 2 所示。
AppScan 使用流程,AppScan 執(zhí)行過程的一個(gè)分解,如圖 3。
精確測(cè)試的方法,目的是為了檢測(cè)是否存在 CSRF 保護(hù)。對(duì) CSRF 保護(hù)有個(gè)范圍約束的問題,并不是所有的請(qǐng)求都需要對(duì) CSRF 攻擊做防范。對(duì)靜態(tài)資源除非有 DELETE/PUT 操作允許的情況下,才需要進(jìn)行測(cè)試;而對(duì)于關(guān)鍵的業(yè)務(wù)邏輯,比如銀行轉(zhuǎn)帳,確認(rèn)收貨人信息,參加競(jìng)標(biāo),刪除一個(gè)用戶,賦予用戶高級(jí)權(quán)限,等等,對(duì)這類定性問題的約束是根據(jù)不同的商業(yè)產(chǎn)品各異,要具體問題具體分析。
本例以常見的頁面刪除為實(shí)例,闡述一個(gè)可以的測(cè)試方法。大概分為以下幾種情況 :
使用 GET 來刪除頁面的,使用 DELETE/PUT 來刪除頁面的,使用 POST 來刪除頁面的,都是服務(wù)器與客戶端的交互過程,具體的實(shí)例分析起來要遠(yuǎn)比分類更為復(fù)雜,一個(gè)操作可能帶有很多各樣的請(qǐng)求,找到有威脅的請(qǐng)求才是最終目的,有時(shí)候哪怕是 AppScan 已經(jīng)定位到具體是那個(gè)請(qǐng)求,也還需要通過手工將這個(gè)案例找出加以描述成為有實(shí)際操作價(jià)值的場(chǎng)景,這里就需要引入手工測(cè)試工具加以支持。
手工工具的介紹,做精確測(cè)試需要對(duì) HTTP 請(qǐng)求做頻繁的操作,如果需要查看請(qǐng)求的內(nèi)容,還有對(duì)具體請(qǐng)求的操作的觀察,推薦使用 Fiddler 或者 WebScarab。
開始手動(dòng)驗(yàn)證之前,還需要清楚 CSRF 發(fā)生的條件。所有的問題的發(fā)生有個(gè)前提條件是用戶常用的瀏覽器中有一個(gè)與目標(biāo)服務(wù)器處于激活狀態(tài)的會(huì)話。這個(gè)條件需要的原因是,CSRF 攻擊的模式是用戶 A 被惡意用戶 B 所攻擊,攻擊是 B 發(fā)起的被用戶 A 執(zhí)行實(shí)現(xiàn)的。
而 B 往往是在 A 常去的網(wǎng)站注入代碼,或者發(fā)送鏈接或者包含附件的文件給 A,而包含著惡意代碼或者鏈接的頁面要被執(zhí)行,條件是用戶 A 已經(jīng)處在和服務(wù)器的會(huì)話之中,這也是 CSRF 發(fā)生的前提條件,也是手工測(cè)試的基礎(chǔ)。
GET 請(qǐng)求的情況下,請(qǐng)求如 http://mysite/service?action=delete&pageid=100001
這類問題的驗(yàn)證最為直接,并且無需寫腳本和使用 fiddler 工具去觀察實(shí)際的請(qǐng)求的格式。檢測(cè)方法就是在維持一個(gè)與服務(wù)器連接的前提下,在瀏覽器地址欄輸入如下網(wǎng)址,如果實(shí)際的頁面被刪除了就是 CSRF 攻擊成功了。對(duì)于如此清楚的實(shí)例基本看到 URL 已經(jīng)可以證明沒有任何 CSRF 保護(hù)。
可關(guān)聯(lián)的攻擊場(chǎng)景如下,在任何可以顯示圖片的地方寫入如下 <img src=http://mysite/service?action=delete&pageid=100001 width=0 height=0/>
,另外只需要指引有刪除權(quán)限的用戶訪問一下包含這個(gè)圖片標(biāo)簽的網(wǎng)頁,往往是通過發(fā)一個(gè)郵件或者 MSN 一個(gè)簡(jiǎn)單的鏈接就可以完成刪除頁面的操作。
POST 請(qǐng)求的操作并不能免除 CSRF 的攻擊。在瀏覽器中要發(fā)出 POST 請(qǐng)求,可以使用兩種方法,一個(gè)是通過腳本調(diào)用頁面文檔元素 form 直接進(jìn)行提交操作,特點(diǎn)是可以進(jìn)行跨域的腳本提交,隱式攻擊。另一種是通過使用 Ajax 對(duì)象直接發(fā)出請(qǐng)求,但是由于不能跨域發(fā)出請(qǐng)求,可執(zhí)行的力度并不高,但是還是有可能性。同樣是一個(gè)刪除頁面的操作,如下所示結(jié)構(gòu)。
POST http://mysite/serviceHeaders….Action=delete&pageid=100001
這個(gè)不同于 GET 之處是不能簡(jiǎn)單的通過在瀏覽器直接輸入一個(gè)鏈接就能測(cè)試。需要借助一下預(yù)設(shè)好的 HTTP 服務(wù)器如 IBM HTTP Server、Domino,或者 IIS。將 IFrame.html 的清單拷貝到服務(wù)器的一個(gè)目錄。通過修改 frame1.html 中的 csrf_hack() 如下。
function csrf_hack() { var fields; fields += "<input type='' name='action' value='"+"delete"+"'>"; fields += "<input type='' name=pageid value='"+"1000001" +"'>"; unescape(fields); post('http://mysite/service ',fields); alert("csrf_end");}
可關(guān)聯(lián)的攻擊場(chǎng)景如下 ,通過郵件或者 MSN 發(fā)送一個(gè)鏈接 http://hackerWebServer/iframe
給可以刪除頁面的用戶,該操作就會(huì)被執(zhí)行,如果頁面刪除,攻擊成功。通過在其他網(wǎng)站可以做腳本注入的將 iframe.html 腳本寫在該網(wǎng)站,一樣可以達(dá)到攻擊效果。
另一類通過 Ajax 提交的 post 請(qǐng)求,這類結(jié)構(gòu)中多采用 SOAP message 或者類似的 XML 消息體,或者 Jason 消息體提交請(qǐng)求。結(jié)構(gòu)如下。
POST http://mysite/serviceHeaders….<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header><serviceVersion>8.0.0</serviceVersion></soap:Header><soap:Body><deleteDocument xmlns="http://webservices.clb.content.ibm.com"> <path>/@Pcsrftestplace/@RMain.nsf/@F/@DE44FD4FF0956D07648257570002C42DA</path></deleteDocument></soap:Body></soap:Envelope>
在此類情況下,需要修改 form 的表單的 enctype 屬性為 multipart/form-data,因?yàn)樵谀J(rèn)的情況下是 application/x-www-form-urlencoded,所有字符都會(huì)做 URL 編碼轉(zhuǎn)換,提交的數(shù)據(jù)是不合法的無法被服務(wù)器端識(shí)別,所以需要修改 enctype 屬性,在 multipart/formdata 的情況下,數(shù)據(jù)是不會(huì)被編碼的,而在很多服務(wù)器的接收端有的就是使用 multipart/formdata 去接受數(shù)據(jù)。由于 javascript 出于對(duì)安全的考慮禁止腳本自動(dòng)修改 form 中提交的 file 屬性的輸入的值,所以想通過腳本修改控制 enctype 是不允許的,這樣不同于第一類 POST 請(qǐng)求。但是并不影響場(chǎng)景的合理性,通過在有漏洞的網(wǎng)站偽造表單請(qǐng)求,form 指向我們要操作的 URL 即可。這種情況下,需要構(gòu)造一個(gè)完整的表單,并通過用戶點(diǎn)擊一個(gè)任意方式發(fā)送的鏈接達(dá)到攻擊效果。
DELETE/PUT 請(qǐng)求依賴于 Web 2.0 技術(shù),由于本身的限制,自由發(fā)出跨站的偽造請(qǐng)求是不可能的。更多使用的是離線攻擊,或者本站點(diǎn)的腳本注入攻擊。在存在本站點(diǎn)腳本注入攻擊的情況下,所有這 4 種情況下,都可以完成隱式的攻擊方式。代碼請(qǐng)參照 Web 2.0 攻擊章節(jié)的實(shí)例。
CSRF 的防范機(jī)制有很多種,防范的方法也根據(jù) CSRF 攻擊方式的不斷升級(jí)而不斷演化。常用的有檢查 Refer 頭部信息,使用一次性令牌,使用驗(yàn)證圖片等手段。出于性能的考慮,如果每個(gè)請(qǐng)求都加入令牌驗(yàn)證將極大的增加服務(wù)器的負(fù)擔(dān),具體采用那種方法更合理,需要謹(jǐn)慎審視每種保護(hù)的優(yōu)缺點(diǎn)。
1. 檢查 HTTP 頭部 Refer 信息,這是防止 CSRF 的最簡(jiǎn)單容易實(shí)現(xiàn)的一種手段。根據(jù) RFC 對(duì)于 HTTP 協(xié)議里面 Refer 的定義,Refer 信息跟隨出現(xiàn)在每個(gè) Http 請(qǐng)求頭部。Server 端在收到請(qǐng)求之后,可以去檢查這個(gè)頭信息,只接受來自本域的請(qǐng)求而忽略外部域的請(qǐng)求,這樣就可以避免了很多風(fēng)險(xiǎn)。當(dāng)然這種檢查方式由于過于簡(jiǎn)單也有它自身的弱點(diǎn):
a) 首先是檢查 Refer 信息并不能防范來自本域的攻擊。在企業(yè)業(yè)務(wù)網(wǎng)站上,經(jīng)常會(huì)有同域的論壇,郵件等形式的 Web 應(yīng)用程序存在,來自這些地方的 CSRF 攻擊所攜帶的就是本域的 Refer 域信息,因此不能被這種防御手段所阻止。
b) 同樣,某些直接發(fā)送 HTTP 請(qǐng)求的方式(指非瀏覽器,比如用后臺(tái)代碼等方法)可以偽造一些 Refer 信息,雖然直接進(jìn)行頭信息偽造的方式屬于直接發(fā)送請(qǐng)求,很難跟隨發(fā)送 cookie,但由于目前客戶端手段層出不窮,flash,javascript 等大規(guī)模使用,從客戶端進(jìn)行 refer 的偽造,尤其是在客戶端瀏覽器安裝了越來越多的插件的情況下已經(jīng)成為可能了。
2. 使用一次性令牌,這是當(dāng)前 Web 應(yīng)用程序的設(shè)計(jì)人員廣泛使用的一種方式,方法是對(duì)于 Get 請(qǐng)求,在 URL 里面加入一個(gè)令牌,對(duì)于 Post 請(qǐng)求,在隱藏域中加入一個(gè)令牌。這個(gè)令牌由 server 端生成,由編程人員控制在客戶端發(fā)送請(qǐng)求的時(shí)候使請(qǐng)求攜帶本令牌然后在 Server 端進(jìn)行驗(yàn)證。但在令牌的設(shè)計(jì)上目前存在著幾個(gè)錯(cuò)誤的方案:
a) 使用和 Session 獨(dú)立的令牌生成方式。這種令牌的值和 Session 無關(guān),因此容易被其他用戶偽造。這里的其他用戶指的是當(dāng)前 Web 應(yīng)用程序的其他用戶和活躍在網(wǎng)絡(luò)傳輸階段各個(gè)設(shè)置上的監(jiān)聽者,這種惡意用戶可能使用自己的令牌來進(jìn)行替換以便達(dá)到偽造的目的。
b) 完全使用 Session 認(rèn)證信息作為令牌的生成方式。這種保護(hù)方式對(duì)于保護(hù) CSRF 是起了作用的,但是可能會(huì)造成其他危害,具體來說,如果某些 URL 或者網(wǎng)頁被拷貝下來與其他人共享,那么這些 URL 或者拷貝下來的網(wǎng)頁中可能會(huì)含有用戶的會(huì)話信息,這種信息一旦被惡意用戶獲得,就能造成極大的危害。
因此,一個(gè)正確的令牌設(shè)計(jì)應(yīng)該是使用 Session 信息做 Hash,用得出的哈希值來做 CSRF 的令牌。
3. 使用驗(yàn)證圖片,這種方法的出現(xiàn)的作用是對(duì)于機(jī)器人暴力攻擊的防止。但在 CSRF 的防范上,也有一些安全性要求比較高的的應(yīng)用程序結(jié)合驗(yàn)證圖片和一次性令牌來做雙重保護(hù)。由于這種圖片驗(yàn)證信息很難被惡意程序在客戶端識(shí)別,因此能夠提高更強(qiáng)的保護(hù)。當(dāng)客戶端的瀏覽器可能已經(jīng)處于一種不安全的環(huán)境中的情況下(比如客戶端的安全級(jí)別設(shè)置較低,客戶端瀏覽器安裝了不安全的插件等)。
以上給的這些只是防范 CSRF 的比較通用的一些方法,Web 開發(fā)人員可以根據(jù)自己對(duì)自己的應(yīng)用程序的功能的理解來確定安全級(jí)別的要求從而選擇使用不同的保護(hù)措施,也推薦在同一應(yīng)用程序內(nèi)部結(jié)合使用多種方法來進(jìn)行保護(hù)。
CSRF 攻擊作為一個(gè)存在已久的攻擊方式,在大量的商業(yè)網(wǎng)站上都可以找出,應(yīng)用本文的知識(shí)作出一個(gè)合理的分析,有針對(duì)性的提出改進(jìn)方案才是本文作者希望看到的,在即不損害應(yīng)用程序的性能的前提下,提高安全性;而對(duì)即將開發(fā)的網(wǎng)絡(luò)應(yīng)用程序來說,深刻理解其的危害性,在設(shè)計(jì)階段就考慮到對(duì) CSRF 的防范,無疑能收到更好的效果。
聯(lián)系客服