在開發(fā) OAuth認(rèn)證服務(wù)器 的時(shí)候狸驳,開發(fā)者的安全意識不高的話,很可能會忽略 state 參數(shù),從而導(dǎo)致 出現(xiàn) csrf 漏洞跷坝。
但是在說明這個(gè)state參數(shù)前,有必要了解大部分程序員所寫的綁定OAuth賬號流程碉碉,由于綁定流程很多柴钻,這里挑最常見的“用戶在第三方網(wǎng)站A上登錄后,通過Authorization code方式綁定微博流程(也是這個(gè)漏洞常見的場景流程):
1垢粮、用戶甲到第三方網(wǎng)站A登錄后贴届,到了綁定頁面。此時(shí)還沒綁定微博蜡吧。綁定頁面提供一個(gè)按鈕:“綁定微博”(地址a: http://aaa.com/index.php?m=user_3rd_bind_sina )
2毫蚓、用戶甲點(diǎn)擊地址a,程序生成如下地址b(為方便大家查看昔善,參數(shù)部分均未urlencode以【】包含顯示): https://api.weibo.com/oauth2/authorize?client_id=【9999999】&redirect_uri=【http://aaa.comindex.php?m=user_3rd_bind_sina_callback】&response_type=【code】
3元潘、用戶甲瀏覽器定向到地址b,授權(quán)該應(yīng)用君仆。
4翩概、授權(quán)服務(wù)器根據(jù)傳遞的redirect_uri參數(shù),組合認(rèn)證參數(shù)code生成地址c: http://aaa.comindex.php?m=user_3rd_bind_sina_callback&code=【809ui0asduve】
5返咱、用戶甲瀏覽器返回到地址c钥庇,完成綁定。
咋看起來咖摹,好像沒啥問題评姨,畢竟code也是不可預(yù)測嘛。但是各開發(fā)者有沒有想過萤晴,地址c實(shí)質(zhì)上是和當(dāng)前登錄用戶一點(diǎn)關(guān)系都沒有的吐句,因?yàn)榈刂穋只能證明微博用戶信息胁后,但無法證明網(wǎng)站A的用戶信息。所以漏洞就此產(chǎn)生了——假設(shè)有用戶乙和丙嗦枢,同時(shí)發(fā)起綁定請求攀芯,登錄到不同的微博賬號,然后在第5步后打住净宵,互相交換地址c敲才,會是什么結(jié)果?答案就是用戶乙綁定了用戶丙的微博择葡,用戶丙綁定了用戶乙的微博了…...攻擊者的目標(biāo)紧武,其實(shí)就是要獲取地址c,然后誘騙已登錄網(wǎng)站A的受害者點(diǎn)擊敏储,從而改變了綁定關(guān)系阻星。
為應(yīng)對這種情況,Oauth 2.0引入了state參數(shù)已添。這個(gè)參數(shù)在許多開放平臺上也會有提及妥箕,比如新浪微博的 Oauth2/authorize(http://open.weibo.com/wiki/Oauth2/authorize ): 用于保持請求和回調(diào)的狀態(tài),在回調(diào)時(shí)更舞,會在Query Parameter中回傳該參數(shù)畦幢。開發(fā)者可以用這個(gè)參數(shù)驗(yàn)證請求有效性,也可以記錄用戶請求授權(quán)頁前的位置缆蝉。這個(gè)參數(shù)可用于防止跨站請求偽造(CSRF)攻擊宇葱。然而大多數(shù)開發(fā)者(包括許多官方SDK),會忽略使用這個(gè)state參數(shù)刊头。所以黍瞧,大面積的網(wǎng)站(不乏大站)確實(shí)存在這種漏洞。
但是利用條件也有點(diǎn)苛刻原杂。
攻擊者必須了解第三方網(wǎng)站可能的綁定特性印颤,否則攻擊極可能失敗。絕大多數(shù)網(wǎng)站都是一個(gè)網(wǎng)站賬號只能綁定一個(gè)OAuth提供方賬號(比如微博帳號)穿肄。這種特性年局,導(dǎo)致這個(gè)漏洞在絕大多數(shù)網(wǎng)站根本無法快速撒網(wǎng),只能定向劫持未綁定的用戶到攻擊者OAuth賬號上被碗,而攻擊一次后某宪,這個(gè)賬號必須解綁才能用于別的攻擊,導(dǎo)致利用難度增大不少锐朴。
攻擊者還必須了解被定向劫持用戶的上網(wǎng)習(xí)慣。在這個(gè)漏洞中蔼囊,絕大部分都需要受害者在第三方網(wǎng)站上處于登錄狀態(tài)焚志,否則攻擊基本失效衣迷。
攻擊者還必須了解第三方網(wǎng)站、以及用戶在該第三方網(wǎng)站上存在的利益〗闯辏現(xiàn)在的攻擊有許多都是帶有利益的壶谒,如果是電商類的話,網(wǎng)站本身的金錢利益驅(qū)動可能存在膳沽,但又需要判斷該用戶在該網(wǎng)站是否存在高價(jià)值汗菜,這就增加了額外的工作量;如果只是娛樂類網(wǎng)站挑社,除了言論相關(guān)和用戶所擁有的網(wǎng)站管理權(quán)陨界,我還想不出有什么可以吸引攻擊者去定向攻擊。
以上各種條件造就了在攻擊實(shí)施環(huán)節(jié)更像是那種一對一的淘寶或者QQ釣魚手段痛阻、或者放入針對高價(jià)值目標(biāo)的社工(或APT)一環(huán)中菌瘪。就前者而言,淘寶阱当、QQ甚至各類熱門游戲的釣魚量之大俏扩,安全研究者們應(yīng)該更清楚;就后者而言弊添,實(shí)質(zhì)還有其它更有效地手段录淡。那么,這個(gè)漏洞油坝,還能冠以“最大規(guī)模帳號劫持”嗎嫉戚?我相信,地下產(chǎn)業(yè)者看到后只會輕蔑的笑一下免钻,然后繼續(xù)埋頭干活
對于開發(fā)者而言彼水,要修復(fù)這個(gè)漏洞,就是必須加入state參數(shù)极舔,這個(gè)參數(shù)既不可預(yù)測凤覆,又必須可以充分證明client和當(dāng)前第三方網(wǎng)站的登錄認(rèn)證狀態(tài)存在關(guān)聯(lián)(如果存在過期時(shí)間更好)。其實(shí)拆魏,隨機(jī)算一個(gè)字符串盯桦,然后保存在session,回調(diào)時(shí)檢查state參數(shù)和session里面的值渤刃,就滿足要求了拥峦。