CSRF & CORS
下面轉(zhuǎn)的兩篇文章分別說明了以下兩個(gè)概念和一些解決方法:
1. CSRF - Cross-Site Request Forgery - 跨站請求偽造
2. CORS - Cross Origin Resourse-Sharing - 跨站資源共享
(1. CSRF)轉(zhuǎn)自:http://www.h3c.com.cn/About_H3C/Company_Publication/IP_Lh/2012/04/Home/Catalog/201208/751467_30008_0.htm
從下面文章中可以知道為什么要設(shè)置csrf_token,以及為什么一些網(wǎng)站把csrf_token放入header或url。
1 CSRF漏洞簡介
CSRF(Cross-Site Request Forgery奶浦,跨站點(diǎn)偽造請求)是一種網(wǎng)絡(luò)攻擊方式淤击,該攻擊可以在受害者毫不知情的情況下以受害者名義偽造請求發(fā)送給受攻擊站點(diǎn),從而在未授權(quán)的情況下執(zhí)行在權(quán)限保護(hù)之下的操作,具有很大的危害性紊遵。具體來講账千,可以這樣理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義發(fā)送惡意請求癞蚕,對服務(wù)器來說這個(gè)請求是完全合法的蕊爵,但是卻完成了攻擊者所期望的一個(gè)操作,比如以你的名義發(fā)送郵件桦山、發(fā)消息攒射,盜取你的賬號,添加系統(tǒng)管理員恒水,甚至于購買商品会放、虛擬貨幣轉(zhuǎn)賬等。
CSRF攻擊方式并不為大家所熟知钉凌,實(shí)際上很多網(wǎng)站都存在CSRF的安全漏洞咧最。早在2000年,CSRF這種攻擊方式已經(jīng)由國外的安全人員提出御雕,但在國內(nèi)矢沿,直到2006年才開始被關(guān)注。2008年酸纲,國內(nèi)外多個(gè)大型社區(qū)和交互網(wǎng)站先后爆出CSRF漏洞捣鲸,如:百度HI、NYTimes.com(紐約時(shí)報(bào))闽坡、Metafilter(一個(gè)大型的BLOG網(wǎng)站)和YouTube等栽惶。但直到現(xiàn)在,互聯(lián)網(wǎng)上的許多站點(diǎn)仍對此毫無防備疾嗅,以至于安全業(yè)界稱CSRF為“沉睡的巨人”外厂,其威脅程度由此“美譽(yù)”便可見一斑。
2 CSRF攻擊原理及實(shí)例
CSRF攻擊原理
CSRF攻擊原理比較簡單代承,如圖1所示汁蝶。其中Web A為存在CSRF漏洞的網(wǎng)站,Web B為攻擊者構(gòu)建的惡意網(wǎng)站次泽,User C為Web A網(wǎng)站的合法用戶穿仪。
圖1 CSRF攻擊原理
- 用戶C打開瀏覽器,訪問受信任網(wǎng)站A意荤,輸入用戶名和密碼請求登錄網(wǎng)站A啊片;
2.在用戶信息通過驗(yàn)證后,網(wǎng)站A產(chǎn)生Cookie信息并返回給瀏覽器玖像,此時(shí)用戶登錄網(wǎng)站A成功紫谷,可以正常發(fā)送請求到網(wǎng)站A齐饮;
用戶未退出網(wǎng)站A之前,在同一瀏覽器中笤昨,打開一個(gè)TAB頁訪問網(wǎng)站B祖驱;
網(wǎng)站B接收到用戶請求后,返回一些攻擊性代碼瞒窒,并發(fā)出一個(gè)請求要求訪問第三方站點(diǎn)A捺僻;
瀏覽器在接收到這些攻擊性代碼后,根據(jù)網(wǎng)站B的請求崇裁,在用戶不知情的情況下攜帶Cookie信息匕坯,向網(wǎng)站A發(fā)出請求。網(wǎng)站A并不知道該請求其實(shí)是由B發(fā)起的拔稳,所以會(huì)根據(jù)用戶C的Cookie信息以C的權(quán)限處理該請求葛峻,導(dǎo)致來自網(wǎng)站B的惡意代碼被執(zhí)行。
CSRF攻擊分類
CSRF漏洞一般分為站外和站內(nèi)兩種類型巴比。
CSRF站外類型的漏洞本質(zhì)上就是傳統(tǒng)意義上的外部提交數(shù)據(jù)問題术奖。通常程序員會(huì)考慮給一些留言或者評論的表單加上水印以防止SPAM問題(這里,SPAM可以簡單的理解為垃圾留言轻绞、垃圾評論采记,或者是帶有站外鏈接的惡意回復(fù)),但是有時(shí)為了提高用戶的體驗(yàn)性政勃,可能沒有對一些操作做任何限制挺庞,所以攻擊者可以事先預(yù)測并設(shè)置請求的參數(shù),在站外的Web頁面里編寫腳本偽造文件請求稼病,或者和自動(dòng)提交的表單一起使用來實(shí)現(xiàn)GET、POST請求掖鱼,當(dāng)用戶在會(huì)話狀態(tài)下點(diǎn)擊鏈接訪問站外Web頁面然走,客戶端就被強(qiáng)迫發(fā)起請求。
CSRF站內(nèi)類型的漏洞在一定程度上是由于程序員濫用
REQUEST類變量造成的戏挡。在一些敏感的操作中(如修改密碼芍瑞、添加用戶等),本來要求用戶從表單提交發(fā)起POST請求傳遞參數(shù)給程序褐墅,但是由于使用了_REQUEST等變量拆檬,程序除支持接收POST請求傳遞的參數(shù)外也支持接收GET請求傳遞的參數(shù),這樣就會(huì)為攻擊者使用CSRF攻擊創(chuàng)造條件妥凳。一般攻擊者只要把預(yù)測的請求參數(shù)放在站內(nèi)一個(gè)貼子或者留言的圖片鏈接里竟贯,受害者瀏覽了這樣的頁面就會(huì)被強(qiáng)迫發(fā)起這些請求。
CSRF攻擊實(shí)例
下面以Axous 1.1.1 CSRF Add Admin Vulnerability(漏洞CVE編號:CVE-2012-2629)為例逝钥,介紹CSRF攻擊具體實(shí)施過程屑那。
Axous是一款網(wǎng)上商店應(yīng)用軟件。Axous 1.1.1以及更低版本在實(shí)現(xiàn)上存在一個(gè)CSRF漏洞,遠(yuǎn)程攻擊者可以通過構(gòu)造特制的網(wǎng)頁持际,誘使該軟件管理員訪問沃琅,成功利用此漏洞的攻擊者可以添加系統(tǒng)管理員。利用此漏洞主要包含以下三個(gè)過程:
攻擊者構(gòu)造惡意網(wǎng)頁蜘欲。在實(shí)施攻擊前益眉,攻擊者需要構(gòu)造一個(gè)與正常添加管理員用戶基本一樣的網(wǎng)頁,在該惡意網(wǎng)頁中對必要的參數(shù)項(xiàng)進(jìn)行賦值姥份,并將該網(wǎng)頁的action指向正常添加管理員用戶時(shí)訪問的URL郭脂,核心代碼如圖2所示;
攻擊者利用社會(huì)工程學(xué)誘使Axous系統(tǒng)管理員訪問其構(gòu)造的惡意網(wǎng)頁殿衰;
執(zhí)行惡意代碼朱庆。當(dāng)系統(tǒng)管理員訪問惡意網(wǎng)頁時(shí),惡意代碼在管理員不知情的情況下以系統(tǒng)管理員的合法權(quán)限被執(zhí)行闷祥,攻擊者偽造的管理員賬戶添加成功娱颊。
圖2 CSRF攻擊添加管理員核心代碼
3 CSRF 漏洞檢測
檢測CSRF漏洞是一項(xiàng)比較繁瑣的工作,最簡單的方法就是抓取一個(gè)正常請求的數(shù)據(jù)包凯砍,去掉Referer字段后再重新提交箱硕,如果該提交還有效,那么基本上可以確定存在CSRF漏洞悟衩。
隨著對CSRF漏洞研究的不斷深入剧罩,不斷涌現(xiàn)出一些專門針對CSRF漏洞進(jìn)行檢測的工具,如CSRFTester座泳,CSRF Request Builder等惠昔。
以CSRFTester工具為例,CSRF漏洞檢測工具的測試原理如下:使用CSRFTester進(jìn)行測試時(shí)挑势,首先需要抓取我們在瀏覽器中訪問過的所有鏈接以及所有的表單等信息镇防,然后通過在CSRFTester中修改相應(yīng)的表單等信息,重新提交潮饱,這相當(dāng)于一次偽造客戶端請求来氧。如果修改后的測試請求成功被網(wǎng)站服務(wù)器接受,則說明存在CSRF漏洞香拉,當(dāng)然此款工具也可以被用來進(jìn)行CSRF攻擊啦扬。
4 CSRF漏洞防御
CSRF漏洞防御主要可以從三個(gè)層面進(jìn)行,即服務(wù)端的防御凫碌、用戶端的防御和安全設(shè)備的防御扑毡。
4.1 服務(wù)端的防御
目前業(yè)界服務(wù)器端防御CSRF攻擊主要有三種策略:驗(yàn)證HTTP Referer字段,在請求地址中添加token并驗(yàn)證证鸥,在HTTP頭中自定義屬性并驗(yàn)證僚楞。下面分別對這三種策略進(jìn)行簡要介紹勤晚。
4.1.1 驗(yàn)證HTTP Referer字段
根據(jù)HTTP協(xié)議,在HTTP頭中有一個(gè)字段叫Referer泉褐,它記錄了該HTTP請求的來源地址赐写。在通常情況下,訪問一個(gè)安全受限頁面的請求必須來自于同一個(gè)網(wǎng)站膜赃。比如某銀行的轉(zhuǎn)賬是通過用戶訪問http://bank.test/test?page=10&userID=101&money=10000頁面完成挺邀,用戶必須先登錄bank. test,然后通過點(diǎn)擊頁面上的按鈕來觸發(fā)轉(zhuǎn)賬事件跳座。當(dāng)用戶提交請求時(shí)端铛,該轉(zhuǎn)賬請求的Referer值就會(huì)是轉(zhuǎn)賬按鈕所在頁面的URL(本例中,通常是以bank. test域名開頭的地址)疲眷。而如果攻擊者要對銀行網(wǎng)站實(shí)施CSRF攻擊禾蚕,他只能在自己的網(wǎng)站構(gòu)造請求,當(dāng)用戶通過攻擊者的網(wǎng)站發(fā)送請求到銀行時(shí)狂丝,該請求的Referer是指向攻擊者的網(wǎng)站换淆。因此,要防御CSRF攻擊几颜,銀行網(wǎng)站只需要對于每一個(gè)轉(zhuǎn)賬請求驗(yàn)證其Referer值倍试,如果是以bank. test開頭的域名,則說明該請求是來自銀行網(wǎng)站自己的請求蛋哭,是合法的县习。如果Referer是其他網(wǎng)站的話,就有可能是CSRF攻擊谆趾,則拒絕該請求躁愿。
4.1.2 在請求地址中添加token并驗(yàn)證
CSRF攻擊之所以能夠成功,是因?yàn)楣粽呖梢詡卧煊脩舻恼埱蠡ε睿撜埱笾兴械挠脩趄?yàn)證信息都存在于Cookie中攘已,因此攻擊者可以在不知道這些驗(yàn)證信息的情況下直接利用用戶自己的Cookie來通過安全驗(yàn)證。由此可知怜跑,抵御CSRF攻擊的關(guān)鍵在于:在請求中放入攻擊者所不能偽造的信息,并且該信息不存在于Cookie之中吠勘。鑒于此性芬,系統(tǒng)開發(fā)者可以在HTTP請求中以參數(shù)的形式加入一個(gè)隨機(jī)產(chǎn)生的token,并在服務(wù)器端建立一個(gè)攔截器來驗(yàn)證這個(gè)token剧防,如果請求中沒有token或者token內(nèi)容不正確植锉,則認(rèn)為可能是CSRF攻擊而拒絕該請求。
4.1.3 在HTTP頭中自定義屬性并驗(yàn)證
自定義屬性的方法也是使用token并進(jìn)行驗(yàn)證峭拘,和前一種方法不同的是俊庇,這里并不是把token以參數(shù)的形式置于HTTP請求之中狮暑,而是把它放到HTTP頭中自定義的屬性里。通過XMLHttpRequest這個(gè)類辉饱,可以一次性給所有該類請求加上csrftoken這個(gè)HTTP頭屬性搬男,并把token值放入其中。這樣解決了前一種方法在請求中加入token的不便彭沼,同時(shí)缔逛,通過這個(gè)類請求的地址不會(huì)被記錄到瀏覽器的地址欄,也不用擔(dān)心token會(huì)通過Referer泄露到其他網(wǎng)站姓惑。
4.2 用戶端的防御
對于普通用戶來說褐奴,都學(xué)習(xí)并具備網(wǎng)絡(luò)安全知識(shí)以防御網(wǎng)絡(luò)攻擊是不現(xiàn)實(shí)的。但若用戶養(yǎng)成良好的上網(wǎng)習(xí)慣于毙,則能夠很大程度上減少CSRF攻擊的危害敦冬。例如,用戶上網(wǎng)時(shí)唯沮,不要輕易點(diǎn)擊網(wǎng)絡(luò)論壇脖旱、聊天室、即時(shí)通訊工具或電子郵件中出現(xiàn)的鏈接或者圖片烂翰;及時(shí)退出長時(shí)間不使用的已登錄賬戶夯缺,尤其是系統(tǒng)管理員,應(yīng)盡量在登出系統(tǒng)的情況下點(diǎn)擊未知鏈接和圖片甘耿。除此之外踊兜,用戶還需要在連接互聯(lián)網(wǎng)的計(jì)算機(jī)上安裝合適的安全防護(hù)軟件,并及時(shí)更新軟件廠商發(fā)布的特征庫佳恬,以保持安全軟件對最新攻擊的實(shí)時(shí)跟蹤捏境。
跨域資源共享(CORS)安全性淺析
(轉(zhuǎn)自http://netsecurity.51cto.com/art/201311/419179.htm)
一、背景
提起瀏覽器的同源策略毁葱,大家都很熟悉垫言。不同域的客戶端腳本不能讀寫對方的資源。但是實(shí)踐中有一些場景需要跨域的讀寫倾剿,所以出現(xiàn)了一些hack的方式來跨域筷频。比如在同域內(nèi)做一個(gè)代理,JSON-P等前痘。但這些方式都存在缺陷凛捏,無法完美的實(shí)現(xiàn)跨域讀寫。所以在XMLHttpRequest v2標(biāo)準(zhǔn)下芹缔,提出了CORS(Cross Origin Resourse-Sharing)的模型坯癣,試圖提供安全方便的跨域讀寫資源。目前主流瀏覽器均支持CORS最欠。
二示罗、技術(shù)原理
CORS定義了兩種跨域請求惩猫,簡單跨域請求和非簡單跨域請求。當(dāng)一個(gè)跨域請求發(fā)送簡單跨域請求包括:請求方法為HEAD蚜点,GET轧房,POST;請求頭只有4個(gè)字段,Accept禽额,Accept-Language锯厢,Content-Language,Last-Event-ID;如果設(shè)置了Content-Type脯倒,則其值只能是application/x-www-form-urlencoded,multipart/form-data,text/plain实辑。說起來比較別扭,簡單的意思就是設(shè)置了一個(gè)白名單藻丢,符合這個(gè)條件的才是簡單請求剪撬。其他不符合的都是非簡單請求。
之所以有這個(gè)分類是因?yàn)闉g覽器對簡單請求和非簡單請求的處理機(jī)制是不一樣的悠反。當(dāng)我們需要發(fā)送一個(gè)跨域請求的時(shí)候残黑,瀏覽器會(huì)首先檢查這個(gè)請求,如果它符合上面所述的簡單跨域請求斋否,瀏覽器就會(huì)立刻發(fā)送這個(gè)請求梨水。如果瀏覽器檢查之后發(fā)現(xiàn)這是一個(gè)非簡單請求,比如請求頭含有X-Forwarded-For字段茵臭。這時(shí)候?yàn)g覽器不會(huì)馬上發(fā)送這個(gè)請求疫诽,而是有一個(gè)preflight,跟服務(wù)器驗(yàn)證的過程旦委。瀏覽器先發(fā)送一個(gè)options方法的預(yù)檢請求奇徒。下圖是一個(gè)示例。如果預(yù)檢通過缨硝,則發(fā)送這個(gè)請求摩钙,否則就不拒絕發(fā)送這個(gè)跨域請求。
下面詳細(xì)分析一下實(shí)現(xiàn)安全跨域請求的控制方式查辩。先看一下非簡單請求的預(yù)檢過程胖笛。瀏覽器先發(fā)送一個(gè)options方法的請求。帶有如下字段:
Origin: 普通的HTTP請求也會(huì)帶有宜岛,在CORS中專門作為Origin信息供后端比對,表明來源域匀钧。
Access-Control-Request-Method: 接下來請求的方法,例如PUT, DELETE等等
Access-Control-Request-Headers: 自定義的頭部谬返,所有用setRequestHeader方法設(shè)置的頭部都將會(huì)以逗號隔開的形式包含在這個(gè)頭中
然后如果服務(wù)器配置了cors,會(huì)返回對應(yīng)對的字段日杈,具體字段含義在返回結(jié)果是一并解釋遣铝。
Access-Control-Allow-Origin:
Access-Control-Allow-Methods:
Access-Control-Allow-Headers:
然后瀏覽器再根據(jù)服務(wù)器的返回值判斷是否發(fā)送非簡單請求佑刷。簡單請求前面講過是直接發(fā)送,只是多加一個(gè)origin字段表明跨域請求的來源酿炸。然后服務(wù)器處理完請求之后瘫絮,會(huì)再返回結(jié)果中加上如下控制字段:
Access-Control-Allow-Origin: 允許跨域訪問的域,可以是一個(gè)域的列表填硕,也可以是通配符"*"麦萤。這里要注意Origin規(guī)則只對域名有效,并不會(huì)對子目錄有效扁眯。即http://foo.example/subdir/ 是無效的壮莹。但是不同子域名需要分開設(shè)置,這里的規(guī)則可以參照同源策略
Access-Control-Allow-Credentials: 是否允許請求帶有驗(yàn)證信息姻檀,這部分將會(huì)在下面詳細(xì)解釋
Access-Control-Expose-Headers: 允許腳本訪問的返回頭命满,請求成功后,腳本可以在XMLHttpRequest中訪問這些頭的信息(貌似webkit沒有實(shí)現(xiàn)這個(gè))
Access-Control-Max-Age: 緩存此次請求的秒數(shù)绣版。在這個(gè)時(shí)間范圍內(nèi)胶台,所有同類型的請求都將不再發(fā)送預(yù)檢請求而是直接使用此次返回的頭作為判斷依據(jù),非常有用杂抽,大幅優(yōu)化請求次數(shù)
Access-Control-Allow-Methods: 允許使用的請求方法诈唬,以逗號隔開
Access-Control-Allow-Headers: 允許自定義的頭部,以逗號隔開缩麸,大小寫不敏感
然后瀏覽器通過返回結(jié)果的這些控制字段來決定是將結(jié)果開放給客戶端腳本讀取還是屏蔽掉铸磅。如果服務(wù)器沒有配置cors,返回結(jié)果沒有控制字段匙睹,瀏覽器會(huì)屏蔽腳本對返回信息的讀取愚屁。
三、安全隱患
大家注意這個(gè)流程痕檬。服務(wù)器接收到跨域請求的時(shí)候霎槐,并沒有先驗(yàn)證,而是先處理了請求梦谜。所以從某種程度上來說丘跌。在支持cors的瀏覽器上實(shí)現(xiàn)跨域的寫資源,打破了傳統(tǒng)同源策略下不能跨域讀寫資源唁桩。
再一個(gè)就是如果程序猿偷懶將Access-Control-Allow-Origin設(shè)置為允許來自所有域的跨域請求闭树。那么cors的安全機(jī)制幾乎就無效了。不過先別高興的太早荒澡。其實(shí)這里在設(shè)計(jì)的時(shí)候有一個(gè)很好的限制报辱。xmlhttprequest發(fā)送的請求需要使用“withCredentials”來帶上cookie,如果一個(gè)目標(biāo)域設(shè)置成了允許任意域的跨域請求单山,這個(gè)請求又帶著cookie的話碍现,這個(gè)請求是不合法的幅疼。(就是如果需要實(shí)現(xiàn)帶cookie的跨域請求,需要明確的配置允許來源的域昼接,使用任意域的配置是不合法的)瀏覽器會(huì)屏蔽掉返回的結(jié)果爽篷。javascript就沒法獲取返回的數(shù)據(jù)了。這是cors模型最后一道防線慢睡。假如沒有這個(gè)限制的話逐工,那么javascript就可以獲取返回?cái)?shù)據(jù)中的csrf token,以及各種敏感數(shù)據(jù)漂辐。這個(gè)限制極大的降低了cors的風(fēng)險(xiǎn)泪喊。
四、攻擊模型
從思路上講者吁,有兩種類型的攻擊方式窘俺。一種是在攻擊者自己控制的網(wǎng)頁上嵌入跨域請求,用戶訪問鏈接复凳,執(zhí)行了跨域請求瘤泪,從而攻擊目標(biāo),比如訪問了內(nèi)網(wǎng)敏感資源育八。還有一種是正常的網(wǎng)頁被嵌入了到攻擊者控制頁面的跨域請求对途,從而劫持用戶的會(huì)話。
五髓棋、攻擊場景
先看第一種思路的攻擊場景:
1,復(fù)雜csrf实檀。傳統(tǒng)的csrf都是利用html標(biāo)簽和表單來發(fā)送請求。沒有辦法實(shí)現(xiàn)一些復(fù)雜步驟的csrf按声,比如模擬購物膳犹,先加購物車,結(jié)算签则,填寫信息须床,等等。比如上傳文件渐裂。具體可以參考利用csrf上傳文件
2,訪問內(nèi)網(wǎng)敏感資源豺旬。這個(gè)在一定的條件下是可以實(shí)現(xiàn)的。比如內(nèi)網(wǎng)的服務(wù)器配置了
Access-Control-Allow-Origin: * 允許任何來自任意域的跨域請求
用戶訪問惡意網(wǎng)頁的時(shí)候柒凉,執(zhí)行了到內(nèi)網(wǎng)服務(wù)器192.168.1.123/password.txt的請求族阅,腳本在接收到服務(wù)器返回之后,將內(nèi)容發(fā)送到攻擊者的服務(wù)器上膝捞。
第二種思路的場景:
1,交互式xss坦刀。參考揭密HTML5帶來的攻擊手法中講到的shell of the future工具。通過cors,繞過一些反會(huì)話劫持的方法鲤遥,如HTTP-Only限制的cookie央渣,綁定IP地址的會(huì)話ID等,劫持用戶會(huì)話渴频。
2,程序猿在寫ajax請求的時(shí)候,對目標(biāo)域限制不嚴(yán)北启。有點(diǎn)類似于url跳轉(zhuǎn)卜朗。facebook出現(xiàn)過這樣一個(gè)案例。javascript通過url里的參數(shù)進(jìn)行ajax請求咕村。通過控制這個(gè)參數(shù)實(shí)現(xiàn)注入攻擊场钉。