WEB安全中經(jīng)常談到的兩個東西:XSS和CSRF图筹。這兩個概念在前端面試中也經(jīng)常被問到,只要涉及到WEB安全的東西就必須提到他們哥倆扣溺,從我以往的面試經(jīng)歷中我多次死在這兩個東西上瓜晤,知道這兩個東西但讓我仔細描述下就瞎幾把亂扯,結(jié)果可想而知痢掠。這幾天也查閱了相關書籍,終于把這兩個東西搞明白了雄驹,為此決定寫篇文章來記錄他們倆以備今后復習淹辞,這篇先介紹CSRF。
CSRF是什么鬼
CSRF(Cross Site Request Forgery) 跨站請求偽造蔬将。也被稱為One Click Attack和Session Riding央星,通常縮寫為CSRF或XSRF等曼。如果從名字你還不不知道它表示什么,你可以這樣理解:攻擊者(黑客胁黑,釣魚網(wǎng)站)盜用了你的身份州泊,以你的名義發(fā)送惡意請求,這些請求包括發(fā)送郵件遥皂、發(fā)送消息演训、盜取賬號、購買商品样悟、銀行轉(zhuǎn)賬庭猩,從而使你的個人隱私泄露和財產(chǎn)損失陈症。
CSRF漏洞現(xiàn)狀
CSRF這種攻擊方式在2000年已經(jīng)被國外的安全人員提出录肯,但在國內(nèi),直到2006年才開始被關注论咏,2008年,國內(nèi)外的多個大型社區(qū)和交互網(wǎng)站分別爆出CSRF漏洞穿剖,如:紐約時報卦溢,Metafilter,YouTube和百度单寂。。蘸劈。尊沸。而現(xiàn)在,互聯(lián)網(wǎng)的許多站點仍對此毫無防備棒掠,以至于安全業(yè)界稱CSRF為“沉睡的巨人”屁商。
CSRF攻擊實例
聽了這么多,可能大家還云里霧里蜡镶,光聽概念可能大家對于CSRF還是不夠了解官还,下面我將舉一個例子來讓大家對CSRF有一個更深層次的理解。
我們先假設支付寶存在CSRF漏洞妻枕,我的支付寶賬號是lyq粘驰,攻擊者的支付寶賬號是xxx述么。然后我們通過網(wǎng)頁請求的方式 http://zhifubao.com/withdraw?account=lyq&amount=10000&for=lyq2 可以把我賬號lyq的10000元轉(zhuǎn)到我的另外一個賬號lyq2上去度秘。通常情況下饵撑,該請求發(fā)送到支付寶服務器后,服務器會先驗證該請求是否來自一個合法的session并且該session的用戶已經(jīng)成功登陸滑潘。攻擊者在支付吧也有賬號xxx,他知道上文中的URL可以進行轉(zhuǎn)賬操作追逮,于是他自己可以發(fā)送一個請求 http://zhifubao.com/withdraw?account=lyq&amount=10000&for=xxx 到支付寶后臺粹舵。但是這個請求是來自攻擊者而不是來自我lyq,所以不能通過安全認證巴席,因此該請求作廢诅需。這時,攻擊者xxx想到了用CSRF的方式堰塌,他自己做了個黃色網(wǎng)站,在網(wǎng)站中放了如下代碼:http://zhifubao.com/withdraw?account=lyq&amount=10000&for=xxx 并且通過黃色鏈接誘使我來訪問他的網(wǎng)站料睛。當我禁不住誘惑時就會點了進去摇邦,上述請求就會從我自己的瀏覽器發(fā)送到支付寶,而且這個請求會附帶我的瀏覽器中的cookie居扒。大多數(shù)情況下丑慎,該請求會失敗瓤摧,因為支付寶要求我的認證信息玉吁,但是我如果剛訪問支付寶不久,還沒有關閉支付寶頁面这揣,我的瀏覽器中的cookie存有我的認證信息影斑,這個請求就會得到響應
,從我的賬戶中轉(zhuǎn)10000元到xxx賬戶里片迅,而我絲毫不知情皆辽,攻擊者拿到錢后逍遙法外。所以以后一定要克制住自己唯蝶,不要隨便打開別人的鏈接遗嗽。
CSRF原理
下面一張圖簡單闡述了CSRF的原理
從上圖可以看出,要完成一次CSRF攻擊征字,受害者必須依次完成以下兩個步驟:
- 登錄受信任網(wǎng)站A娇豫,并在本地生成Cookie。
- 在不登出A的情況下冯痢,訪問危險網(wǎng)站B浦楣。
看到這里,你也許會問:“如果我不滿足以上兩個條件中的一個振劳,我就不會受到CSRF攻擊”历恐。是滴专筷,確實如此蒸苇,但是你不能保證以下情況不會發(fā)生:
- 你不能保證你登錄了一個網(wǎng)站之后,不再打開一個tab頁面并訪問其它的網(wǎng)站(黃網(wǎng))填渠。
- 你不能保證你關閉瀏覽器之后氛什,你本地的Cookie立刻過期匪凉,你上次的會話已經(jīng)結(jié)束。
- 上述中所謂的攻擊網(wǎng)站再层,可能就是一個釣魚網(wǎng)站或者黃色網(wǎng)站聂受。
CSRF如何防御
驗證HTTP Referer字段
根據(jù)HTTP協(xié)議,在HTTP頭部中有一個Referer字段蛋济,它記錄了該HTTP請求所在的地址,表示HTTP請求從那個頁面發(fā)出的渡处。比如當你訪問 http://zhifubao.com/withdraw?account=lyq&amount=10000&for=xxx 祟辟,用戶必須先登錄支付寶網(wǎng)站,然后通過點擊頁面的的按鈕來觸發(fā)轉(zhuǎn)賬事件醇份。此時吼具,轉(zhuǎn)賬請求的Referer值就是轉(zhuǎn)賬頁面所在的URL,通常是以zhifubao.com域名開頭的地址畔濒。如果攻擊者要實行CSRF攻擊锣咒,那么他只能在自己的站點構(gòu)造請求赞弥,此時Referer的值就指向黑客自己的網(wǎng)站趣兄。因此要防御CSRF攻擊,支付寶只需要對每一個轉(zhuǎn)賬請求驗證其Referer值拼窥,如果是以zhifubao.com開頭的域名蹋凝,則是合法請求,相反改含,則是非法請求并拒絕迄汛。
這種方法的好處就是簡單易行,只需要在后臺添加一個攔截器來檢查Referer即可鹃觉。然而這種辦法并不是萬無一失睹逃,Referer的值是由瀏覽器提供的,一些低級的瀏覽器可以通過某種方式篡改Referer的值唯卖,這就給了攻擊者可乘之機拜轨;而一些高級瀏覽器處于安全考慮,可以讓用戶設置發(fā)送HTTP請求時不再提供Referer值橄碾,這樣當他們正常訪問支付寶網(wǎng)站時法牲,因為沒有提供Referer值而被誤認為CERF攻擊,拒絕訪問拒垃。實際應用中通常采用第二種方法來防御CSRF攻擊。
添加token驗證
CSRF攻擊之所以能夠成功戈毒,是因為攻擊者可以完全偽造用戶的請求,該請求中所有的用戶驗證信息都存在cookie中冠桃,因此攻擊者可以在不知道這些驗證信息的情況下直接利用用戶自己的cookie來通過安全驗證道宅。要防止CSRF,關鍵在于在請求中放入黑客所不能偽造的信息樱报,并且該信息不存在于cookie之中省咨。可以在HTTP請求中以參數(shù)的形式加入一個隨機產(chǎn)生的token,并在服務器建立一個攔截器來驗證這個token穷缤,如果請求中沒有token或者token不正確津肛,則認為可能是CSRF攻擊而拒絕該請求。
現(xiàn)在業(yè)界一致的做法就是使用Anti CSRF Token來防御CSRF身坐。
- 用戶訪問某個表單頁面部蛇。
- 服務端生成一個Token,放在用戶的Session中涯鲁,或者瀏覽器的Cookie中。
- 在頁面表單附帶上Token參數(shù)岛请。
- 用戶提交請求后警绩,服務端驗證表單中的Token是否與用戶Session(或Cookies)中的Token一致,一致為合法請求后室,不是則非法請求。
這個Token值必須是隨機的逞盆,不可預測的松申。由于Token的存在,攻擊者無法再構(gòu)造一個帶有合法Token的請求實施CSRF攻擊舅逸。另外使用Token應注意Token的保密性皇筛,盡量把敏感操作由GET改成POST,以form或者AJAX形式提交旗笔,避免Token泄露拄踪。
驗證碼
驗證碼,強制用戶必須與應用進行交互撮弧,才能完成最終請求姚糊。通常情況下,驗證碼能夠很好的遏制CSRF攻擊贸辈。但是出于用戶體驗考慮忿薇,網(wǎng)站不能給所有的操作都加上驗證碼。因此驗證碼只能作為一種輔助手段揉燃。
盡量使用POST筋栋,限制GET
GET接口能夠直接將請求地址暴露給攻擊者,所以要防止CSRF一定最好不要用GET抢腐。當然POST并不是萬無一失,攻擊者只需要構(gòu)造一個form表單就可以伤靠,但需要在第三方頁面做啼染,這樣就增加了暴露的可能性。
在HTTP頭部添加自定義屬性
這種方法也是使用token并驗證卦洽,但是它是把token放在HTTP請求頭部中斜棚。通過使用AJAX我們可以在我們的請求頭部中添加我們的自定義屬性,但是這種方法要求我們將整個站的請求全部改成AJAX蚤霞,如果是新站還好粗梭,老站的話無疑是需要重寫整個站點的,這是很不可取的。
好了奏纪,CSRF講完了序调,下篇文章我們介紹XSS跨站腳本攻擊。