https://juejin.im/post/5bc009996fb9a05d0a055192
這個(gè)頁面只要打開婚脱,就會(huì)向Gmail發(fā)送一個(gè)post請(qǐng)求齐佳。請(qǐng)求中锭弊,執(zhí)行了“Create Filter”命令船惨,將所有的郵件柜裸,轉(zhuǎn)發(fā)到“hacker@hakermail.com”。小明由于剛剛就登陸了Gmail粱锐,所以這個(gè)請(qǐng)求發(fā)送時(shí)疙挺,攜帶著小明的登錄憑證(Cookie),Gmail的后臺(tái)接收到請(qǐng)求怜浅,驗(yàn)證了確實(shí)有小明的登錄憑證铐然,于是成功給小明配置了過濾器蔬崩。黑客可以查看小明的所有郵件,包括郵件里的域名驗(yàn)證碼等隱私信息搀暑。拿到驗(yàn)證碼之后沥阳,黑客就可以要求域名服務(wù)商把域名重置給自己。小明很快打開Gmail自点,找到了那條過濾器桐罕,將其刪除。然而桂敛,已經(jīng)泄露的郵件功炮,已經(jīng)被轉(zhuǎn)讓的域名,再也無法挽回了......
什么是CSRF
CSRF(Cross-site request forgery)跨站請(qǐng)求偽造:攻擊者誘導(dǎo)受害者進(jìn)入第三方網(wǎng)站埠啃,在第三方網(wǎng)站中死宣,向被攻擊網(wǎng)站發(fā)送跨站請(qǐng)求伟恶。利用受害者在被攻擊網(wǎng)站已經(jīng)獲取的注冊(cè)憑證碴开,繞過后臺(tái)的用戶驗(yàn)證,達(dá)到冒充用戶對(duì)被攻擊的網(wǎng)站執(zhí)行某項(xiàng)操作的目的博秫。
一個(gè)典型的CSRF攻擊有著如下的流程:
受害者登錄a.com潦牛,并保留了登錄憑證(Cookie)。
b.com?向?a.com?發(fā)送了一個(gè)請(qǐng)求:a.com/act=xx巴碗。瀏覽器會(huì)…
a.com接收到請(qǐng)求后,對(duì)請(qǐng)求進(jìn)行驗(yàn)證即寒,并確認(rèn)是受害者的憑證橡淆,誤以為是受害者自己發(fā)送的請(qǐng)求。
a.com以受害者的名義執(zhí)行了act=xx母赵。
攻擊完成逸爵,攻擊者在受害者不知情的情況下,冒充受害者凹嘲,讓a.com執(zhí)行了自己定義的操作师倔。
幾種常見的攻擊類型
GET類型的CSRF
GET類型的CSRF利用非常簡單,只需要一個(gè)HTTP請(qǐng)求周蹭,一般會(huì)這樣利用:
在受害者訪問含有這個(gè)img的頁面后趋艘,瀏覽器會(huì)自動(dòng)向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker發(fā)出一次HTTP請(qǐng)求。bank.example就會(huì)收到包含受害者登錄信息的一次跨域請(qǐng)求凶朗。
POST類型的CSRF
這種類型的CSRF利用起來通常使用的是一個(gè)自動(dòng)提交的表單
訪問該頁面后瓷胧,表單會(huì)自動(dòng)提交,相當(dāng)于模擬用戶完成了一次POST操作棚愤。
POST類型的攻擊通常比GET要求更加嚴(yán)格一點(diǎn)搓萧,但仍并不復(fù)雜。任何個(gè)人網(wǎng)站、博客矛绘,被黑客上傳頁面的網(wǎng)站都有可能是發(fā)起攻擊的來源耍休,后端接口不能將安全寄托在僅允許POST上面。
鏈接類型的CSRF
鏈接類型的CSRF并不常見货矮,比起其他兩種用戶打開頁面就中招的情況羊精,這種需要用戶點(diǎn)擊鏈接才會(huì)觸發(fā)。這種類型通常是在論壇中發(fā)布的圖片中嵌入惡意鏈接囚玫,或者以廣告的形式誘導(dǎo)用戶中招喧锦,攻擊者通常會(huì)以比較夸張的詞語誘騙用戶點(diǎn)擊,例如:
重磅消息Wザ健燃少!復(fù)制代碼
由于之前用戶登錄了信任的網(wǎng)站A,并且保存登錄狀態(tài)铃在,只要用戶主動(dòng)訪問上面的這個(gè)PHP頁面阵具,則表示攻擊成功。
CSRF的特點(diǎn)
攻擊一般發(fā)起在第三方網(wǎng)站定铜,而不是被攻擊的網(wǎng)站阳液。被攻擊的網(wǎng)站無法防止攻擊發(fā)生。
攻擊利用受害者在被攻擊網(wǎng)站的登錄憑證揣炕,冒充受害者提交操作帘皿;而不是直接竊取數(shù)據(jù)。
整個(gè)過程攻擊者并不能獲取到受害者的登錄憑證畸陡,僅僅是“冒用”鹰溜。
跨站請(qǐng)求可以用各種方式:圖片URL、超鏈接丁恭、CORS曹动、Form提交等等。部分請(qǐng)求方式可以直接嵌入在第三方論壇涩惑、文章中仁期,難以進(jìn)行追蹤。
CSRF通常是跨域的竭恬,因?yàn)橥庥蛲ǔ8菀妆还粽哒瓶仵说啊5侨绻居蛳掠腥菀妆焕玫墓δ埽热缈梢园l(fā)圖和鏈接的論壇和評(píng)論區(qū)痊硕,攻擊可以直接在本域下進(jìn)行赊级,而且這種攻擊更加危險(xiǎn)。
防護(hù)策略
CSRF通常從第三方網(wǎng)站發(fā)起岔绸,被攻擊的網(wǎng)站無法防止攻擊發(fā)生理逊,只能通過增強(qiáng)自己網(wǎng)站針對(duì)CSRF的防護(hù)能力來提升安全性拙绊。
上文中講了CSRF的兩個(gè)特點(diǎn):
CSRF(通常)發(fā)生在第三方域名春锋。
CSRF攻擊者不能獲取到Cookie等信息,只是使用。
針對(duì)這兩點(diǎn)贞瞒,我們可以專門制定防護(hù)策略胎许,如下:
阻止不明外域的訪問:同源檢測(cè)柑司、Samesite Cookie
提交時(shí)要求附加本域才能獲取的信息:CSRF Token踊餐、雙重Cookie驗(yàn)證
CSRF Token
前面講到CSRF的另一個(gè)特征是,攻擊者無法直接竊取到用戶的信息(Cookie欲侮,Header崭闲,網(wǎng)站內(nèi)容等),僅僅是冒用Cookie中的信息威蕉。
而CSRF攻擊之所以能夠成功刁俭,是因?yàn)榉?wù)器誤把攻擊者發(fā)送的請(qǐng)求當(dāng)成了用戶自己的請(qǐng)求。那么我們可以要求所有的用戶請(qǐng)求都攜帶一個(gè)CSRF攻擊者無法獲取到的Token韧涨。服務(wù)器通過校驗(yàn)請(qǐng)求是否攜帶正確的Token牍戚,來把正常的請(qǐng)求和攻擊的請(qǐng)求區(qū)分開,也可以防范CSRF的攻擊氓奈。
原理
CSRF Token的防護(hù)策略分為三個(gè)步驟:
1.將CSRF Token輸出到頁面中
首先翘魄,用戶打開頁面的時(shí)候鼎天,服務(wù)器需要給這個(gè)用戶生成一個(gè)Token舀奶,該Token通過加密算法對(duì)數(shù)據(jù)進(jìn)行加密,一般Token都包括隨機(jī)字符串和時(shí)間戳的組合斋射,顯然在提交時(shí)Token不能再放在Cookie中了育勺,否則又會(huì)被攻擊者冒用。因此罗岖,為了安全起見Token最好還是存在服務(wù)器的Session中涧至,之后在每次頁面加載時(shí),使用JS遍歷整個(gè)DOM樹桑包,對(duì)于DOM中所有的a和form標(biāo)簽后加入Token南蓬。這樣可以解決大部分的請(qǐng)求,但是對(duì)于在頁面加載之后動(dòng)態(tài)生成的HTML代碼哑了,這種方法就沒有作用赘方,還需要程序員在編碼時(shí)手動(dòng)添加Token。
2.頁面提交的請(qǐng)求攜帶這個(gè)Token
對(duì)于GET請(qǐng)求弱左,Token將附在請(qǐng)求地址之后窄陡,這樣URL 就變成?http://url?csrftoken=tokenvalue。?而對(duì)于 POST 請(qǐng)求來說拆火,要在 form 的最后加上:
這樣跳夭,就把Token以參數(shù)的形式加入請(qǐng)求了涂圆。
3.服務(wù)器驗(yàn)證Token是否正確
當(dāng)用戶從客戶端得到了Token,再次提交給服務(wù)器的時(shí)候币叹,服務(wù)器需要判斷Token的有效性润歉,驗(yàn)證過程是先解密Token,對(duì)比加密字符串以及時(shí)間戳颈抚,如果加密字符串一致且時(shí)間未過期卡辰,那么這個(gè)Token就是有效的。
雙重Cookie驗(yàn)證
在會(huì)話中存儲(chǔ)CSRF Token比較繁瑣邪意,而且不能在通用的攔截上統(tǒng)一處理所有的接口九妈。
那么另一種防御措施是使用雙重提交Cookie。利用CSRF攻擊不能獲取到用戶Cookie的特點(diǎn)雾鬼,我們可以要求Ajax和表單請(qǐng)求攜帶一個(gè)Cookie中的值萌朱。
雙重Cookie采用以下流程:
在用戶訪問網(wǎng)站頁面時(shí),向請(qǐng)求域名注入一個(gè)Cookie策菜,內(nèi)容為隨機(jī)字符串(例如csrfcookie=v8g9e4ksfhw)晶疼。
在前端向后端發(fā)起請(qǐng)求時(shí),取出Cookie又憨,并添加到URL的參數(shù)中(接上例POST https://www.a.com/comment?csrfcookie=v8g9e4ksfhw)翠霍。
后端接口驗(yàn)證Cookie中的字段與URL參數(shù)中的字段是否一致,不一致則拒絕蠢莺。
總結(jié)
用雙重Cookie防御CSRF的優(yōu)點(diǎn):
無需使用Session寒匙,適用面更廣,易于實(shí)施躏将。
Token儲(chǔ)存于客戶端中锄弱,不會(huì)給服務(wù)器帶來壓力。
相對(duì)于Token祸憋,實(shí)施成本更低会宪,可以在前后端統(tǒng)一攔截校驗(yàn),而不需要一個(gè)個(gè)接口和頁面添加蚯窥。
缺點(diǎn):
Cookie中增加了額外的字段掸鹅。
如果有其他漏洞(例如XSS),攻擊者可以注入Cookie拦赠,那么該防御方式失效巍沙。
難以做到子域名的隔離。
為了確保Cookie傳輸安全矛紫,采用這種防御方式的最好確保用整站HTTPS的方式赎瞎,如果還沒切HTTPS的使用這種方式也會(huì)有風(fēng)險(xiǎn)。
Samesite Cookie屬性
防止CSRF攻擊的辦法已經(jīng)有上面的預(yù)防措施颊咬。為了從源頭上解決這個(gè)問題务甥,Google起草了一份草案來改進(jìn)HTTP協(xié)議牡辽,那就是為Set-Cookie響應(yīng)頭新增Samesite屬性,它用來標(biāo)明這個(gè) Cookie是個(gè)“同站 Cookie”敞临,同站Cookie只能作為第一方Cookie态辛,不能作為第三方Cookie,Samesite 有兩個(gè)屬性值挺尿,分別是 Strict 和 Lax
防止網(wǎng)站被利用
前面所說的奏黑,都是被攻擊的網(wǎng)站如何做好防護(hù)。而非防止攻擊的發(fā)生编矾,CSRF的攻擊可以來自:
攻擊者自己的網(wǎng)站熟史。
有文件上傳漏洞的網(wǎng)站。
第三方論壇等用戶內(nèi)容窄俏。
被攻擊網(wǎng)站自己的評(píng)論功能等蹂匹。
對(duì)于來自黑客自己的網(wǎng)站,我們無法防護(hù)凹蜈。但對(duì)其他情況限寞,那么如何防止自己的網(wǎng)站被利用成為攻擊的源頭呢?
嚴(yán)格管理所有的上傳接口仰坦,防止任何預(yù)期之外的上傳內(nèi)容(例如HTML)履植。
添加Header?X-Content-Type-Options: nosniff?防止黑客上傳HTML內(nèi)容的資源(例如圖片)被解析為網(wǎng)頁。
對(duì)于用戶上傳的圖片悄晃,進(jìn)行轉(zhuǎn)存或者校驗(yàn)玫霎。不要直接使用用戶填寫的圖片鏈接。
當(dāng)前用戶打開其他用戶填寫的鏈接時(shí)传泊,需告知風(fēng)險(xiǎn)(這也是很多論壇不允許直接在內(nèi)容中發(fā)布外域鏈接的原因之一鼠渺,不僅僅是為了用戶留存,也有安全考慮)眷细。
CSRF其他防范措施
對(duì)于一線的程序員同學(xué),我們可以通過各種防護(hù)策略來防御CSRF鹃祖,對(duì)于QA溪椎、SRE、安全負(fù)責(zé)人等同學(xué)恬口,我們可以做哪些事情來提升安全性呢校读?
CSRF測(cè)試
CSRFTester是一款CSRF漏洞的測(cè)試工具,CSRFTester工具的測(cè)試原理大概是這樣的祖能,使用代理抓取我們?cè)跒g覽器中訪問過的所有的連接以及所有的表單等信息歉秫,通過在CSRFTester中修改相應(yīng)的表單等信息,重新提交养铸,相當(dāng)于一次偽造客戶端請(qǐng)求雁芙,如果修改后的測(cè)試請(qǐng)求成功被網(wǎng)站服務(wù)器接受轧膘,則說明存在CSRF漏洞,當(dāng)然此款工具也可以被用來進(jìn)行CSRF攻擊兔甘。 CSRFTester使用方法大致分下面幾個(gè)步驟:
步驟1:設(shè)置瀏覽器代理? ? 步驟2:使用合法賬戶訪問網(wǎng)站開始測(cè)試
步驟3:通過CSRF修改并偽造請(qǐng)求? ? 步驟4:拿到結(jié)果如有漏洞進(jìn)行修復(fù)
CSRF監(jiān)控
對(duì)于一個(gè)比較復(fù)雜的網(wǎng)站系統(tǒng)谎碍,某些項(xiàng)目、頁面洞焙、接口漏掉了CSRF防護(hù)措施是很可能的蟆淀。
一旦發(fā)生了CSRF攻擊,我們?nèi)绾渭皶r(shí)的發(fā)現(xiàn)這些攻擊呢澡匪?
CSRF攻擊有著比較明顯的特征:
跨域請(qǐng)求熔任。
GET類型請(qǐng)求Header的MIME類型大概率為圖片,而實(shí)際返回Header的MIME類型為Text唁情、JSON笋敞、HTML。
我們可以在網(wǎng)站的代理層監(jiān)控所有的接口請(qǐng)求荠瘪,如果請(qǐng)求符合上面的特征夯巷,就可以認(rèn)為請(qǐng)求有CSRF攻擊嫌疑。我們可以提醒對(duì)應(yīng)的頁面和項(xiàng)目負(fù)責(zé)人哀墓,檢查或者 Review其CSRF防護(hù)策略趁餐。
個(gè)人用戶CSRF安全的建議
經(jīng)常上網(wǎng)的個(gè)人用戶,可以采用以下方法來保護(hù)自己:
使用網(wǎng)頁版郵件的瀏覽郵件或者新聞也會(huì)帶來額外的風(fēng)險(xiǎn)篮绰,因?yàn)椴榭脆]件或者新聞消息有可能導(dǎo)致惡意代碼的攻擊后雷。
盡量不要打開可疑的鏈接,一定要打開時(shí)吠各,使用不常用的瀏覽器臀突。
總結(jié)
簡單總結(jié)一下上文的防護(hù)策略:
CSRF自動(dòng)防御策略:同源檢測(cè)(Origin 和 Referer 驗(yàn)證)。
CSRF主動(dòng)防御措施:Token驗(yàn)證 或者 雙重Cookie驗(yàn)證 以及配合Samesite Cookie贾漏。
保證頁面的冪等性候学,后端接口不要在GET頁面中做用戶操作。
為了更好的防御CSRF纵散,最佳實(shí)踐應(yīng)該是結(jié)合上面總結(jié)的防御措施方式中的優(yōu)缺點(diǎn)來綜合考慮梳码,結(jié)合當(dāng)前Web應(yīng)用程序自身的情況做合適的選擇,才能更好的預(yù)防CSRF的發(fā)生伍掀。