Web安全之CSRF攻擊,大黑客的超級攻擊!

摘要: CSRF速成講解

CSRF是什麼?

CSRF(Cross Site Request Forgery),中文是跨站點請求偽造。CSRF攻擊者在用戶已經登錄目標網站之後,誘使用戶訪問一個攻擊頁面,利用目標網站對用戶的信任,以用戶身份在攻擊頁面對目標網站發起偽造用戶操作的請求,達到攻擊目的。

舉個例子

簡單版:

假如博客園有個加關注的GET接口,blogUserGuid參數很明顯是關注人Id,如下:

//p2.ttnews.xyz/5e86469b0d8c16be89498fd8.jpg

那我只需要在我的一篇博文內容裡面寫一個img標籤:

那麼只要有人打開我這篇博文,那就會自動關注我。

升級版:

假如博客園還是有個加關注的接口,不過已經限制了只獲取POST請求的數據。這個時候就做一個第三方的頁面,但裡面包含form提交代碼,然後通過QQ、郵箱等社交工具傳播,誘惑用戶去打開,那打開過博客園的用戶就中招了。

在說例子之前要糾正一個iframe問題,有人會直接在第三方頁面這樣寫。如下:

<title>CSRF SHOW/<title>

<iframe>

document.forms.form1.submit();

這樣是用問題的,由於同源策略的原因,iframe內容根本加載不出來,所以裡面form提交當然不會執行。

PS:我嘗試了chrome、IE11、Firefox,情況都是這樣。

所以可以用嵌多一層頁面方式解決,如下:

第一個展示頁面(test):

<title>CSRF SHOW/<title>

<iframe>

第二個隱藏頁面(test2):

<title>CSRF GET/<title>

document.forms.form1.submit();

這樣就可以解決了,有人會問為什麼要加多一層iframe,因為不嵌iframe頁面會重定向,這樣就降低了攻擊的隱蔽性。另外我們test頁面不使用XMLHTTPRequest發送POST請求,是因為有跨域的問題,而form可以跨域post數據。

進階版:

假如博客園還是有個加關注的接口,已經限制POST,但博文內容是直接貼進HTML(未過濾),那就遭受XSS攻擊。那麼就可以直接把上面代碼嵌入博文,那麼只要有人打開我這篇博文,還是會自動關注我,這組合攻擊方式稱為XSRF。

CSRF攻擊的本質原因

CSRF攻擊是源於Web的隱式身份驗證機制!Web的身份驗證機制雖然可以保證一個請求是來自於某個用戶的瀏覽器,但卻無法保證該請求是用戶批准發送的。CSRF攻擊的一般是由服務端解決。

CSRF工具的防禦手段

1. 儘量使用POST,限制GET

GET接口太容易被拿來做CSRF攻擊,看第一個示例就知道,只要構造一個img標籤,而img標籤又是不能過濾的數據。接口最好限制為POST使用,GET則無效,降低攻擊風險。

當然POST並不是萬無一失,攻擊者只要構造一個form就可以,但需要在第三方頁面做,這樣就增加暴露的可能性。

2. 瀏覽器Cookie策略

IE6、7、8、Safari會默認攔截第三方本地Cookie(Third-party Cookie)的發送。但是Firefox2、3、Opera、Chrome、Android等不會攔截,所以通過瀏覽器Cookie策略來防禦CSRF攻擊不靠譜,只能說是降低了風險。

PS:Cookie分為兩種,Session Cookie(在瀏覽器關閉後,就會失效,保存到內存裡),Third-party Cookie(即只有到了Exprie時間後才會失效的Cookie,這種Cookie會保存到本地)。

PS:另外如果網站返回HTTP頭包含P3P Header,那麼將允許瀏覽器發送第三方Cookie。

3. 加驗證碼

驗證碼,強制用戶必須與應用進行交互,才能完成最終請求。在通常情況下,驗證碼能很好遏制CSRF攻擊。但是出於用戶體驗考慮,網站不能給所有的操作都加上驗證碼。因此驗證碼只能作為一種輔助手段,不能作為主要解決方案。

4. Referer Check

Referer Check在Web最常見的應用就是“防止圖片盜鏈”。同理,Referer Check也可以被用於檢查請求是否來自合法的“源”(Referer值是否是指定頁面,或者網站的域),如果都不是,那麼就極可能是CSRF攻擊。

但是因為服務器並不是什麼時候都能取到Referer,所以也無法作為CSRF防禦的主要手段。但是用Referer Check來監控CSRF攻擊的發生,倒是一種可行的方法。

5. Anti CSRF Token

現在業界對CSRF的防禦,一致的做法是使用一個Token(Anti CSRF Token)。

例子:

1. 用戶訪問某個表單頁面。

2. 服務端生成一個Token,放在用戶的Session中,或者瀏覽器的Cookie中。

3. 在頁面表單附帶上Token參數。

4. 用戶提交請求後, 服務端驗證表單中的Token是否與用戶Session(或Cookies)中的Token一致,一致為合法請求,不是則非法請求。

這個Token的值必須是隨機的,不可預測的。由於Token的存在,攻擊者無法再構造一個帶有合法Token的請求實施CSRF攻擊。另外使用Token時應注意Token的保密性,儘量把敏感操作由GET改為POST,以form或AJAX形式提交,避免Token洩露。

注意:

CSRF的Token僅僅用於對抗CSRF攻擊。當網站同時存在XSS漏洞時候,那這個方案也是空談。所以XSS帶來的問題,應該使用XSS的防禦方案予以解決。

總結

CSRF攻擊是攻擊者利用用戶的身份操作用戶帳戶的一種攻擊方式,通常使用Anti CSRF Token來防禦CSRF攻擊,同時要注意Token的保密性和隨機性。


分享到:


相關文章: