邱永哲
(中國(guó)科學(xué)技術(shù)館 網(wǎng)絡(luò)科普部,北京 100012)
隨著互聯(lián)網(wǎng)的高速發(fā)展,各種社交、購(gòu)物網(wǎng)站層出不窮,中國(guó)已經(jīng)全面邁入了互聯(lián)網(wǎng)時(shí)代。對(duì)用戶來(lái)說(shuō),這些繁雜的網(wǎng)站、應(yīng)用程序在方便生活的同時(shí),也引入了個(gè)人信息安全的問(wèn)題。為避免個(gè)人信息遭到泄露,不同的網(wǎng)站設(shè)置不同的賬戶密碼這一方法也逐漸深入人心,成了每個(gè)網(wǎng)民在互聯(lián)網(wǎng)中保護(hù)個(gè)人安全的最有效方法。然而,大量的賬號(hào)和密碼也給用戶帶來(lái)了記憶負(fù)擔(dān),大大降低了使用體驗(yàn)。因此,跨應(yīng)用數(shù)據(jù)共享這一需求逐漸呈現(xiàn)出越來(lái)越高的態(tài)勢(shì),Google,F(xiàn)acebook,騰訊等各大互聯(lián)網(wǎng)廠商也相繼推出了自己的跨應(yīng)用數(shù)據(jù)共享接口,使得用戶在不同網(wǎng)站之間能使用相同的用戶數(shù)據(jù),在提高用戶數(shù)據(jù)安全性的同時(shí)也極大地方便了用戶的使用。
本文通過(guò)介紹跨應(yīng)用授權(quán)協(xié)議OAuth及其運(yùn)行機(jī)制,詳細(xì)闡述了不同應(yīng)用之間數(shù)據(jù)的共享方式和其安全性保護(hù)措施,并列舉了OAuth 2.0協(xié)議在實(shí)施過(guò)程中容易出現(xiàn)的安全問(wèn)題,最后對(duì)開(kāi)發(fā)者提出了相應(yīng)的安全性建議。
開(kāi)放授權(quán)(Open Authorization,OAuth)是一個(gè)開(kāi)放的授權(quán)協(xié)議,其允許用戶讓第三方應(yīng)用訪問(wèn)自己在某一網(wǎng)站上存儲(chǔ)的私密資源(例如照片、視頻、聯(lián)系人等信息),而無(wú)需將用戶名和密碼提供給第三方應(yīng)用。OAuth規(guī)定用戶必須使用一個(gè)訪問(wèn)令牌來(lái)獲取存放在OAuth服務(wù)提供方的數(shù)據(jù),每一個(gè)訪問(wèn)令牌只對(duì)唯一一個(gè)第三方應(yīng)用有效。如圖1所示為國(guó)內(nèi)開(kāi)發(fā)者社區(qū)SegmentFault提供的Google,Github等平臺(tái)OAuth服務(wù)快速登錄接口。
OAuth的出現(xiàn)極大地方便了用戶在不同應(yīng)用之間數(shù)據(jù)的共享需求。2010年4月,OAuth 1.0正式以RFC 5849的形式出現(xiàn),后被全世界廣泛運(yùn)用[1]。目前經(jīng)過(guò)多年的發(fā)展,OAuth授權(quán)協(xié)議已經(jīng)升級(jí)至2.0版本,其官方文檔也已更迭為RFC 6749。
從RFC 6749當(dāng)中可以看到OAuth 2.0的運(yùn)行流程,如圖2所示。
圖中左側(cè)的Client(客戶端)為想要獲取用戶數(shù)據(jù)的第三方應(yīng)用,右側(cè)的Resource owner、Authorization Server、Resource Server均為提供OAuth接口服務(wù)的Server(服務(wù)商)。因此整個(gè)OAuth 2.0的授權(quán)運(yùn)行過(guò)程如下。
圖1 開(kāi)發(fā)者社區(qū)SegmentFault快速登錄接口
圖2 OAuth 2.0運(yùn)行流程
(1)用戶打開(kāi)客戶端后客戶端要求給予授權(quán)。
(2)用戶同意給予客戶端授權(quán)。
(3)用戶使用上一步獲得的授權(quán),向服務(wù)商授權(quán)服務(wù)器申請(qǐng)?jiān)L問(wèn)令牌。
(4)服務(wù)商授權(quán)服務(wù)器對(duì)客戶端確認(rèn)無(wú)誤后同意發(fā)放訪問(wèn)令牌給客戶端。
(5)客戶端使用訪問(wèn)令牌向服務(wù)商資源服務(wù)器獲取相應(yīng)的數(shù)據(jù)。
(6)服務(wù)商資源服務(wù)器確認(rèn)客戶端訪問(wèn)令牌有效,向客戶端開(kāi)放相應(yīng)數(shù)據(jù)。
OAuth 2.0授權(quán)協(xié)議共有4種授權(quán)方式:Authorization code(授權(quán)碼)模式,Implicit(隱式)模式,Resource owner password credentials(賬號(hào)密碼)模式,Client credentials(客戶端)模式。其中,授權(quán)碼模式是目前OAuth 2.0中功能最完善、流程最嚴(yán)密的模式,因而被廣泛使用。這4種授權(quán)方式的流程分別如圖3—6所示。
圖3 Authorization code授權(quán)模式
圖4 Implicit授權(quán)模式
圖5 Resource owner password credentials授權(quán)模式
圖6 Client credentials授權(quán)模式
OAuth 2.0本身是一套非常嚴(yán)密的結(jié)構(gòu),但是一些開(kāi)發(fā)者在實(shí)現(xiàn)、部署OAuth授權(quán)服務(wù)的時(shí)候因?yàn)槭韬龆a(chǎn)生了很多安全問(wèn)題,這些問(wèn)題一旦被利用,將導(dǎo)致嚴(yán)重的后果。下面就列舉一些OAuth 2.0授權(quán)協(xié)議在實(shí)現(xiàn)過(guò)程中容易造成的安全問(wèn)題。
2014年5月,新加坡南洋理工大學(xué)研究人員王晶發(fā)現(xiàn),一些提供OAuth服務(wù)的網(wǎng)站在對(duì)第三方應(yīng)用進(jìn)行OAuth授權(quán)過(guò)程中未對(duì)回調(diào)的統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier,URI)進(jìn)行驗(yàn)證,導(dǎo)致回調(diào)的URI可以被修改為非原定URI,因此可以被用來(lái)釣魚(yú),是一個(gè)明顯的跳轉(zhuǎn)漏洞。這一漏洞被命名為“Covert Redirect”即隱蔽重定向漏洞。
在國(guó)內(nèi),該漏洞也被叫作OAuth redirect_uri回調(diào)污染。事實(shí)上該漏洞造成的危害不僅僅是可被用來(lái)釣魚(yú)攻擊,看下面的例子。假設(shè)某OAuth服務(wù)商使用授權(quán)碼模式進(jìn)行第三方應(yīng)用的授權(quán)服務(wù),某個(gè)第三方應(yīng)用可以通過(guò)該服務(wù)商的OAuth接口綁定賬號(hào),以此來(lái)方便用戶登錄和使用。該客戶端綁定賬號(hào)的請(qǐng)求如下:
GET /authorize?which=Login&display=pc&response_type=code&client_id=100263567&redirect_uri=http://client.com/index.php/sign/callback&scope=get_user_info,add_pic_t,add_t HTTP/1.1
Host: server.com
現(xiàn)在某用戶已經(jīng)登錄了該第三方應(yīng)用,攻擊者向他發(fā)送了如下一個(gè)URL:
http://server.com/authorize?which=Login&display=p c&response_type=code&client_id=100263567&redirect_uri=http://hacker.com/index.php&scope=get_user_info,add_pic_t,add_t
可以看出這是一個(gè)用于綁定賬號(hào)的URL,并且將用于回調(diào)的redirect_uri修改成自己控制的頁(yè)面http://hacker.com/index.php。此時(shí),如果OAuth服務(wù)商存在隱蔽重定向漏洞,那么當(dāng)該用戶點(diǎn)擊并授權(quán)以后頁(yè)面會(huì)跳轉(zhuǎn)至http://hacker.com/index.php?code=***。這時(shí)候該用戶的授權(quán)碼code將會(huì)被hacker.com捕獲便遭到了泄露。對(duì)于一些網(wǎng)站來(lái)說(shuō),授權(quán)碼code一旦泄露,將導(dǎo)致用戶賬號(hào)被劫持,國(guó)內(nèi)騰訊、新浪微博等OAuth服務(wù)均出現(xiàn)過(guò)此問(wèn)題。同時(shí),對(duì)于第三方應(yīng)用來(lái)說(shuō),如果其自身存在XSS或者沒(méi)有做好頁(yè)面防嵌入,也同樣能造成授權(quán)碼code的泄露。
OAuth 2.0當(dāng)中定義了一個(gè)state參數(shù),根據(jù)RFC 6749,其含義為:
state:RECOMMENDED. An opaque value used by the client to maintain state between the request and callback.The authorization server includes this value when redirecting the user-agent back to the client.The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.
即該參數(shù)用于在授權(quán)過(guò)程中請(qǐng)求和回調(diào)階段的狀態(tài)保持,用于防止該過(guò)程中產(chǎn)生CSRF攻擊。然而事實(shí)卻是很多OAuth服務(wù)開(kāi)發(fā)者忘記或錯(cuò)誤使用state參數(shù),造成大量用戶賬號(hào)被劫持的安全事件。國(guó)內(nèi)白帽子黑客horseluke給出了一個(gè)新浪微博的例子[2]。
某用戶在登錄了第三方網(wǎng)站a.com后想在該網(wǎng)站關(guān)聯(lián)并綁定自己的新浪微博賬號(hào),于是就點(diǎn)擊了該網(wǎng)站上給出的“綁定微博”按鈕,該按鈕的URL為http://a.com/index.php?m=user_3rd
_bind_sina。該用戶點(diǎn)擊以后瀏覽器將用戶重定向至新浪微博OAuth授權(quán)頁(yè)面,URL為:http://
api.weibo.com/oaut h 2/aut hor i ze?cl ie nt_id=999999&redirect_uri=http://a.com/index.php?m=user_3rd_
bind_sina_callback&response_type=code。隨后用戶對(duì)a.com給予了授權(quán),新浪微博授權(quán)服務(wù)器生成了授權(quán)碼code,瀏覽器將用戶重定向至http://a.com/index.php?m=user_3rd_bind_sina_callback&
code=809ui0asduve,此時(shí)完成了賬號(hào)綁定。
上述過(guò)程粗略地看并沒(méi)有問(wèn)題,但事實(shí)上完成賬號(hào)綁定時(shí)的URL跟當(dāng)前用戶沒(méi)有任何關(guān)系,因?yàn)樵揢RL只能證明新浪微博用戶信息,但無(wú)法證明a.com的用戶信息?,F(xiàn)在如果有兩個(gè)用戶同時(shí)發(fā)起綁定請(qǐng)求,登錄到不同的微博賬號(hào),隨后在獲取到授權(quán)碼code后雙方互相交換code,這將會(huì)導(dǎo)致兩個(gè)用戶綁定的新浪微博賬戶也發(fā)生交換和改變。黑客正是利用這一點(diǎn)實(shí)現(xiàn)了劫持用戶賬號(hào)的目的,而這一過(guò)程也體現(xiàn)了state參數(shù)的重要性[3]。
2013年,國(guó)內(nèi)著名的音樂(lè)圈APP啪啪被發(fā)現(xiàn)存在任意賬號(hào)登錄的嚴(yán)重漏洞,這一問(wèn)題是啪啪在使用OAuth授權(quán)服務(wù)時(shí)產(chǎn)生的[4]。啪啪客戶端為方便用戶使用,提供了使用新浪微博、QQ登錄的功能,登錄的大致流程為:
(1)用戶點(diǎn)擊使用新浪微博或QQ登錄,將彈出新浪微博或QQ的OAuth授權(quán)頁(yè)。(2)用戶授權(quán)以后啪啪客戶端獲得服務(wù)商提供的訪問(wèn)令牌。(3)啪啪客戶端將訪問(wèn)令牌移交給api.papa.me已獲取啪啪自己的認(rèn)證字符串。(4)啪啪客戶端得到認(rèn)證字符串后獲得操作該微博或QQ綁定的啪啪賬號(hào)權(quán)限。
漏洞發(fā)現(xiàn)者在測(cè)試過(guò)程中,將第二步獲得的訪問(wèn)令牌替換為其他應(yīng)用在OAuth服務(wù)商獲得的訪問(wèn)令牌,隨后繼續(xù)進(jìn)行第三步和第四步,結(jié)果發(fā)現(xiàn)登錄了另一個(gè)啪啪賬號(hào)。該漏洞的關(guān)鍵在于當(dāng)啪啪通過(guò)OAuth服務(wù)商獲得授權(quán)信息(訪問(wèn)令牌、令牌有效期等)后,是將其作為參數(shù)匹配到自己的賬號(hào)并自動(dòng)登錄或自動(dòng)注冊(cè)的。由于后續(xù)的匹配處理邏輯出現(xiàn)紕漏,甚至無(wú)驗(yàn)證機(jī)制,就直接導(dǎo)致了啪啪賬號(hào)的任意登錄。
可見(jiàn),無(wú)論OAuth 2.0是多么嚴(yán)密安全的流程,對(duì)于OAuth服務(wù)商和其使用者來(lái)說(shuō),錯(cuò)誤的實(shí)現(xiàn)和運(yùn)用都可能會(huì)引發(fā)嚴(yán)重的漏洞,以至于大量用戶數(shù)據(jù)和信息也將面臨被劫持泄露的風(fēng)險(xiǎn)。針對(duì)目前發(fā)生過(guò)的一些安全問(wèn)題,本文對(duì)于OAuth在實(shí)現(xiàn)和運(yùn)用過(guò)程中有以下安全建議。
為了防止OAuth授權(quán)過(guò)程產(chǎn)生隱蔽重定向漏洞和redirect_uri回調(diào)污染,OAuth服務(wù)商應(yīng)當(dāng)對(duì)redirect_uri進(jìn)行全路徑校驗(yàn),避免產(chǎn)生跳轉(zhuǎn)漏洞。同時(shí)要加強(qiáng)驗(yàn)證過(guò)程和邏輯,避免被繞過(guò)。
為了防止訪問(wèn)令牌泄露,應(yīng)當(dāng)驗(yàn)證OAuth授權(quán)過(guò)程中的授權(quán)請(qǐng)求來(lái)源信息、第三方應(yīng)用信息。例如在Resource owner password credentials(賬號(hào)密碼)授權(quán)模式中,用戶將在OAuth服務(wù)商的個(gè)人賬戶密碼移交給了第三方應(yīng)用,如果第三方應(yīng)用不被信任,則會(huì)產(chǎn)生用戶數(shù)據(jù)泄露的風(fēng)險(xiǎn)[5]。
使用OAuth的第三方應(yīng)用應(yīng)當(dāng)按照官方文檔的描述,在請(qǐng)求授權(quán)和回調(diào)過(guò)程中正確使用state參數(shù)以防止產(chǎn)生CSRF漏洞,該參數(shù)與anti csrf token類似,要做到隨機(jī)不可預(yù)測(cè)。
使用OAuth的第三方應(yīng)用需要考慮在自動(dòng)登錄或者自動(dòng)注冊(cè)的過(guò)程中,驗(yàn)證OAuth服務(wù)商返回的授權(quán)信息,同時(shí)要驗(yàn)證該授權(quán)信息例如訪問(wèn)令牌是否為指定來(lái)源應(yīng)用所頒發(fā)。第三方應(yīng)用如果發(fā)現(xiàn)了訪問(wèn)令牌中的服務(wù)商給出的uid和自己在服務(wù)商綁定的uid不一致、非自身應(yīng)用appkey授權(quán)的訪問(wèn)令牌、過(guò)期訪問(wèn)令牌等異常情況均需要全部撤銷,并且要求這些異常用戶重新授權(quán)登錄。
由于一些OAuth服務(wù)商在Implicit授權(quán)模式中直接將訪問(wèn)令牌放進(jìn)回調(diào)URL,這就增加了訪問(wèn)令牌泄露的風(fēng)險(xiǎn),因此OAuth服務(wù)商應(yīng)當(dāng)避免第三方應(yīng)用強(qiáng)制更換授權(quán)方式為Implicit模式。
[參考文獻(xiàn)]
[1]佚名.RFC 6749.[EB/OL].(2017-12-29)[2018-03-05].http://www.rfc-editor.org/rfc/rfc6749.txt.
[2]阮一峰. 理解OAuth 2.0[EB/OL].(2014-05-12)[2018-03-05].http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
[3]維基百科.OAuth概念解析[EB/OL].(2017-02-15)[2018-03-05].https://en.wikipedia.org/wiki/OAuth.
[4]HORSELUKE.OAuth 2.0安全案例回顧[EB/OL].(2014-03-11)[2018-03-05].http://wooyun.jozxing.cc/static/drops/papers-598.html.
[5]∑-TEAM.OAuth安全指南[EB/OL].(2014-05-13)[2018-03-05].http://wooyun.jozxing.cc/static/drops/papers-1989.html.