CSRF攻擊與防御原理

CSRF是什么良姆?

(Cross Site Request Forgery, 跨站域請求偽造)是一種網(wǎng)絡(luò)的攻擊方式爵赵,它在 2007 年曾被列為互聯(lián)網(wǎng) 20 大安全隱患之一,也被稱為“One Click Attack”或者Session Riding,通常縮寫為CSRF或者XSRF玻驻,是一種對網(wǎng)站的惡意利用也就是人們所知道的釣魚網(wǎng)站。盡管聽起來像跨站腳本(XSS)违帆,但它與XSS非常不同挣磨,并且攻擊方式幾乎相左。XSS利用站點內(nèi)的信任用戶劣摇,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網(wǎng)站珠移。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防范的資源也相當(dāng)稀少)和難以防范,所以被認為比XSS更具危險性钧惧。

CSRF可以做什么暇韧?

你這可以這么理解 CSRF 攻擊:攻擊者盜用了你的身份,偽裝成你發(fā)送惡意請求浓瞪。CSRF能夠做的事情包括:以你名義發(fā)送郵件懈玻,發(fā)消息,盜取你的賬號乾颁,甚至于購買商品涂乌,虛擬貨幣轉(zhuǎn)賬......造成的問題包括:個人隱私泄露以及財產(chǎn)安全。

它這么厲害钮孵,那它的原理是什么骂倘?

通過下圖來簡述原理

登錄受信任網(wǎng)站A,并在本地生成Cookie巴席。
在不登出A的情況下历涝,訪問危險網(wǎng)站B。
看到這里漾唉,你也許會說:“如果我不滿足以上兩個條件中的一個荧库,我就不會受到CSRF的攻擊”。是的赵刑,確實如此分衫,但你不能保證以下情況不會發(fā)生:
1.你不能保證你登錄了一個網(wǎng)站后,不再打開一個tab頁面并訪問另外的網(wǎng)站般此。
2.你不能保證你關(guān)閉瀏覽器了后蚪战,你本地的Cookie立刻過期,你上次的會話已經(jīng)結(jié)束铐懊。(事實上邀桑,關(guān)閉瀏覽器不能結(jié)束一個會話,但大多數(shù)人都會錯誤的認為關(guān)閉瀏覽器就等于退出登錄/結(jié)束會話了......)
3.上圖中所謂的攻擊網(wǎng)站科乎,可能是一個存在其他漏洞的可信任的經(jīng)常被人訪問的網(wǎng)站壁畸。

詳細的原理介紹

幾種常見的攻擊類型

GET類型的CSRF

這種類型的CSRF一般是由于程序員安全意識不強造成的。GET類型的CSRF利用非常簡單茅茂,只需要一個HTTP請求捏萍,所以,一般會這樣利用:

<img src=http://wooyun.org/csrf?xx=11 /> 

在訪問含有這個img的頁面后空闲,成功向http://wooyun.org/csrf?xx=11 發(fā)出了一次HTTP請求令杈。所以,如果將該網(wǎng)址替換為存在GET型CSRF的地址碴倾,就能完成攻擊了逗噩。

烏云案例

POST類型的CSRF

這種類型的CSRF危害沒有GET型的大悔常,利用起來通常使用的是一個自動提交的表單,如:

<form action=http://wooyun.org/csrf.php method=POST>
    <input type="text" name="xx" value="11" />
</form>
<script> document.forms[0].submit(); </script> 

訪問該頁面后给赞,表單會自動提交,相當(dāng)于模擬用戶完成了一次POST操作矫户。

烏云案例

其他其他猥瑣流CSRF

過基礎(chǔ)認證的CSRF(常用于路由器):

POC:

<img src=http://admin:admin@192.168.1.1 /> 

加載該圖片后片迅,路由器會給用戶一個合法的SESSION,就可以進行下一步操作了皆辽。
烏云案例

防御CSRF的策略

在業(yè)界目前防御 CSRF 攻擊主要有三種策略:驗證 HTTP Referer 字段柑蛇;在請求地址中添加 token 并驗證;在 HTTP 頭中自定義屬性并驗證驱闷。下面就分別對這三種策略進行詳細介紹耻台。

驗證 HTTP Referer 字段

根據(jù) HTTP 協(xié)議,在 HTTP 頭中有一個字段叫 Referer空另,它記錄了該 HTTP 請求的來源地址盆耽。在通常情況下,訪問一個安全受限頁面的請求來自于同一個網(wǎng)站扼菠,比如需要訪問 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory摄杂,用戶必須先登陸 bank.example,然后通過點擊頁面上的按鈕來觸發(fā)轉(zhuǎn)賬事件循榆。因此析恢,要防御 CSRF 攻擊,網(wǎng)站只需要對于每一個轉(zhuǎn)賬請求驗證其 Referer 值秧饮,如果是以 bank.example 開頭的域名映挂,則說明該請求是來自銀行網(wǎng)站自己的請求,是合法的盗尸。如果 Referer 是其他網(wǎng)站的話柑船,則有可能是黑客的 CSRF 攻擊,拒絕該請求振劳。
這種方法的顯而易見的好處就是簡單易行椎组,網(wǎng)站的普通開發(fā)人員不需要操心 CSRF 的漏洞,只需要在最后給所有安全敏感的請求統(tǒng)一增加一個攔截器來檢查 Referer 的值就可以历恐。
然而寸癌,這種方法并非萬無一失。Referer 的值是由瀏覽器提供的弱贼,雖然 HTTP 協(xié)議上有明確的要求蒸苇,但是每個瀏覽器對于 Referer 的具體實現(xiàn)可能有差別,并不能保證瀏覽器自身沒有安全漏洞吮旅。使用驗證 Referer 值的方法溪烤,就是把安全性都依賴于第三方(即瀏覽器)來保障味咳,從理論上來講,這樣并不安全檬嘀。事實上槽驶,對于某些瀏覽器,比如IE6 或 FF2鸳兽,目前已經(jīng)有一些方法可以篡改 Referer 值掂铐。如果 網(wǎng)站支持IE6 瀏覽器,黑客完全可以把用戶瀏覽器的 Referer 值設(shè)為以 bank.example 域名開頭的地址揍异,這樣就可以通過驗證全陨,從而進行 CSRF 攻擊。
即便是使用最新的瀏覽器衷掷,黑客無法篡改 Referer 值辱姨,這種方法仍然有問題。因為 Referer 值會記錄下用戶的訪問來源戚嗅,有些用戶認為這樣會侵犯到他們自己的隱私權(quán)雨涛,特別是有些組織擔(dān)心 Referer 值會把組織內(nèi)網(wǎng)中的某些信息泄露到外網(wǎng)中。因此懦胞,用戶自己可以設(shè)置瀏覽器使其在發(fā)送請求時不再提供 Referer镜悉。當(dāng)他們正常訪問銀行網(wǎng)站時,網(wǎng)站會因為請求沒有 Referer 值而認為是 CSRF 攻擊医瘫,拒絕合法用戶的訪問侣肄。

在請求地址中添加 token 并驗證

CSRF 攻擊之所以能夠成功,是因為黑客可以完全偽造用戶的請求醇份,該請求中所有的用戶驗證信息都是存在于 cookie 中稼锅,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證。要抵御 CSRF僚纷,關(guān)鍵在于在請求中放入黑客所不能偽造的信息矩距,并且該信息不存在于 cookie 之中〔澜撸可以在 HTTP 請求中以參數(shù)的形式加入一個隨機產(chǎn)生的 token锥债,并在服務(wù)器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內(nèi)容不正確痊臭,則認為可能是 CSRF 攻擊而拒絕該請求哮肚。
這種方法要比檢查 Referer 要安全一些,token 可以在用戶登陸后產(chǎn)生并放于 session 之中广匙,然后在每次請求時把 token 從 session 中拿出允趟,與請求中的 token 進行比對,但這種方法的難點在于如何把 token 以參數(shù)的形式加入請求鸦致。對于 GET 請求潮剪,token 將附在請求地址之后涣楷,這樣 URL 就變成 http://url?csrftoken=tokenvalue。 而對于 POST 請求來說抗碰,要在 form 的最后加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>狮斗,這樣就把 token 以參數(shù)的形式加入請求了。但是弧蝇,在一個網(wǎng)站中情龄,可以接受請求的地方非常多,要對于每一個請求都加上 token 是很麻煩的捍壤,并且很容易漏掉,通常使用的方法就是在每次頁面加載時鞍爱,使用 javascript 遍歷整個 dom 樹鹃觉,對于 dom 中所有的 a 和 form 標簽后加入 token。這樣可以解決大部分的請求睹逃,但是對于在頁面加載之后動態(tài)生成的 html 代碼盗扇,這種方法就沒有作用,還需要程序員在編碼時手動添加 token沉填。
該方法還有一個缺點是難以保證 token 本身的安全疗隶。特別是在一些論壇之類支持用戶自己發(fā)表內(nèi)容的網(wǎng)站,黑客可以在上面發(fā)布自己個人網(wǎng)站的地址翼闹。由于系統(tǒng)也會在這個地址后面加上 token斑鼻,黑客可以在自己的網(wǎng)站上得到這個 token,并馬上就可以發(fā)動 CSRF 攻擊猎荠。為了避免這一點坚弱,系統(tǒng)可以在添加 token 的時候增加一個判斷,如果這個鏈接是鏈到自己本站的关摇,就在后面添加 token荒叶,如果是通向外網(wǎng)則不加。不過输虱,即使這個 csrftoken 不以參數(shù)的形式附加在請求之中些楣,黑客的網(wǎng)站也同樣可以通過 Referer 來得到這個 token 值以發(fā)動 CSRF 攻擊。這也是一些用戶喜歡手動關(guān)閉瀏覽器 Referer 功能的原因宪睹。

在 HTTP 頭中自定義屬性并驗證

這種方法也是使用 token 并進行驗證愁茁,和上一種方法不同的是,這里并不是把 token 以參數(shù)的形式置于 HTTP 請求之中亭病,而是把它放到 HTTP 頭中自定義的屬性里埋市。通過 XMLHttpRequest 這個類,可以一次性給所有該類請求加上 csrftoken 這個 HTTP 頭屬性命贴,并把 token 值放入其中道宅。這樣解決了上種方法在請求中加入 token 的不便食听,同時,通過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄污茵,也不用擔(dān)心 token 會透過 Referer 泄露到其他網(wǎng)站中去樱报。
然而這種方法的局限性非常大。XMLHttpRequest 請求通常用于 Ajax 方法中對于頁面局部的異步刷新泞当,并非所有的請求都適合用這個類來發(fā)起迹蛤,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,從而進行前進襟士,后退盗飒,刷新,收藏等操作陋桂,給用戶帶來不便逆趣。另外,對于沒有進行 CSRF 防護的遺留系統(tǒng)來說嗜历,要采用這種方法來進行防護宣渗,要把所有請求都改為 XMLHttpRequest 請求,這樣幾乎是要重寫整個網(wǎng)站梨州,這代價無疑是不能接受的痕囱。

防御實例

Sailajs框架中的JavaScript 代碼示例

下面將以 JavaScript 為例,對上述三種方法分別用代碼進行示例暴匠。

1.驗證 Referer

// 從 HTTP 頭中取得 Referer 值
 var referer=req.headers.Referer; 
 // 判斷 Referer 是否以 test.example 開頭
 if((referer!=null) && (_.startsWith(referer, “test.example ”)){ 
    // 驗證通過
 }else{ 
    // 驗證失敗鞍恢,返回錯誤
 }

2.驗證請求中的 token

 var session = req.session;

 // 從 session 中得到 csrftoken 屬性
 var  token = session.csrftoken; 
 if(token == null){ 

    // 產(chǎn)生新的 token 放入 session 中
    token = generateToken(); 
    token.csrftoken = token ; 
   return ....
 } else{ 

    // 從 HTTP 頭中取得 csrftoken 
    var  token = req.headers.csrftoken; 

    // 從請求參數(shù)中取得 csrftoken 
    var  xhrToken = req.param('csrftoken'); 
    if(token != null && xhrToken != null && token.equals(xhrToken)){ 
       return ...
    }else{ 
        return ...  // ERROR
    } 
 }
HTTP 頭中自定義屬性(網(wǎng)上例子)
var plainXhr = dojo.xhr; 

 // 重寫 dojo.xhr 方法
 dojo.xhr = function(method,args,hasBody) { 
    // 確保 header 對象存在
    args.headers = args.header || {}; 
        
    tokenValue = '<%=request.getSession(false).getAttribute("csrftoken")%>'; 
    var token = dojo.getObject("tokenValue"); 
    
    // 把 csrftoken 屬性放到頭中
    args.headers["csrftoken"] = (token) ? token : "  "; 
    return plainXhr(method,args,hasBody); 
 };

總結(jié)

CSRF 是一種危害非常大的攻擊,又很難以防范每窖。目前幾種防御策略雖然可以很大程度上抵御 CSRF 的攻擊有序,但并沒有一種完美的解決方案。一些新的方案正在研究之中岛请,比如對于每次請求都使用不同的動態(tài)口令旭寿,把 Referer 和 token 方案結(jié)合起來,甚至嘗試修改 HTTP 規(guī)范崇败,但是這些新的方案尚不成熟盅称,要正式投入使用并被業(yè)界廣為接受還需時日。在這之前后室,我們只有充分重視 CSRF缩膝,根據(jù)系統(tǒng)的實際情況選擇最合適的策略,這樣才能把 CSRF 的危害降到最低

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岸霹,一起剝皮案震驚了整個濱河市疾层,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贡避,老刑警劉巖痛黎,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件予弧,死亡現(xiàn)場離奇詭異,居然都是意外死亡湖饱,警方通過查閱死者的電腦和手機掖蛤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來井厌,“玉大人蚓庭,你說我怎么就攤上這事〗銎停” “怎么了器赞?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長墓拜。 經(jīng)常有香客問我港柜,道長,這世上最難降的妖魔是什么撮弧? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮姚糊,結(jié)果婚禮上贿衍,老公的妹妹穿的比我還像新娘。我一直安慰自己救恨,他們只是感情好贸辈,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肠槽,像睡著了一般擎淤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秸仙,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天嘴拢,我揣著相機與錄音,去河邊找鬼寂纪。 笑死席吴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捞蛋。 我是一名探鬼主播孝冒,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拟杉!你這毒婦竟也來了庄涡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤搬设,失蹤者是張志新(化名)和其女友劉穎穴店,沒想到半個月后撕捍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡迹鹅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年卦洽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斜棚。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡阀蒂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弟蚀,到底是詐尸還是另有隱情蚤霞,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布义钉,位于F島的核電站昧绣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏捶闸。R本人自食惡果不足惜夜畴,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望删壮。 院中可真熱鬧贪绘,春花似錦、人聲如沸央碟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亿虽。三九已至菱涤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洛勉,已是汗流浹背粘秆。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留收毫,地道東北人翻擒。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像牛哺,于是被迫代替她去往敵國和親陋气。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • http://www.91ri.org/tag/fuzz-bug 通常情況下引润,有三種方法被廣泛用來防御CSRF攻擊...
    jdyzm閱讀 4,172評論 0 5
  • 轉(zhuǎn)載地址:http://www.phpddt.com/reprint/csrf.htmlCSRF概念:CSRF跨站...
    matianhe閱讀 982評論 0 104
  • CSRF概念:CSRF跨站點請求偽造(Cross—Site Request Forgery)巩趁,跟XSS攻擊一樣,存...
    raincoco閱讀 831評論 0 1
  • CSRF 攻擊的應(yīng)對之道web安全之token和CSRF攻擊CSRF Token 的設(shè)計是否有其必要性? CSRF...
    拾壹北閱讀 408評論 0 1
  • CSRF是什么议慰? (Cross Site Request Forgery, 跨站域請求偽造)是一種網(wǎng)絡(luò)的攻擊方式蠢古,...
    天青色等煙雨閱讀 42,625評論 1 33