從最近幾年開始,做平臺的公司都流行起Open API。這是一個(gè)非常好的理念,也受到廣大開發(fā)者的歡迎。如今,開發(fā)一款軟件,你可以很容易地集成微博、微信、人人網(wǎng)等流行社交媒介的分享功能,做一個(gè)社交應(yīng)用變得越來越簡單。
主流社交媒介要集成到第三方應(yīng)用中,最重要的入口就是安全便捷的授權(quán)認(rèn)證系統(tǒng)。讓用戶在享受一鍵分享和各種社交樂趣的同時(shí),又不用擔(dān)心帳號安全和隱私泄露等問題。而對于一些有特殊目的的組織或個(gè)人來說,攻占這個(gè)授權(quán)認(rèn)證系統(tǒng)意味著自己獲取了信息傳播的入口和渠道,數(shù)量龐大地社交入口往往能帶來巨大的社會效應(yīng)。所以,這個(gè)入口就成了軟件安全攻防雙方的必爭之地。
而本文所要講的就是當(dāng)前最為流行的新浪微博Android客戶端SSO授權(quán)認(rèn)證入口的一個(gè)安全缺陷。此缺陷使得第三方APK在一定條件下可以不通過授權(quán),在不需要人為操作的情況下就可以操作Android手機(jī)用戶的微博。包括關(guān)注、評論、發(fā)微博等OpenAPI中提供的功能。
一、新浪微博授權(quán)認(rèn)證方式的演變:
首先讓我們簡單回顧一下新浪微博OpenAPI這幾年授權(quán)認(rèn)證方式的演變歷程,并了解一下各自的安全性問題。
1、最開始是Basic認(rèn)證。
即是通過http協(xié)議的authorization頭來傳遞認(rèn)證信息。認(rèn)證信息包括用戶名和密碼,僅通過base64對用戶名密碼做加密。基本相當(dāng)于明文傳輸。所以出于賬戶安全考慮,經(jīng)過一段時(shí)間后就被廢棄不用了。
2、然后切換為XAuth認(rèn)證。
XAuth認(rèn)證其實(shí)就是OAuth認(rèn)證的簡化版。OAuth的原理不做詳細(xì)說明。大致流程是:
A、第三方應(yīng)用到授權(quán)服務(wù)器請求一個(gè)授權(quán)令牌(request token&secret)
B、引導(dǎo)用戶到授權(quán)服務(wù)器請求授權(quán)
C、用訪問令牌到授權(quán)服務(wù)器換取訪問令牌(access token&secret)
D、用訪問令牌去訪問得到授權(quán)的資源
它的安全保障是,所有http請求都采用非對稱加密算法對請求進(jìn)行了加密。所以網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)理論上是安全的。
但XAuth認(rèn)證是OAuth認(rèn)證的簡化版,它允許第三方應(yīng)用從用戶的輸入中獲取到用戶的帳號和密碼,而無法保證第三方應(yīng)用對用戶的帳號和密碼進(jìn)行了足夠安全地保護(hù)。特別還有一些流氓軟件本身就會記錄用戶的信息。所以微博帳號的安全還是存在較大的風(fēng)險(xiǎn)。
3、采取了更安全更便捷的OAuth2.0認(rèn)證。
OAuth2.0比OAuth1.0更安全更便捷主要是兩個(gè)方面。
更便捷。OAuth2.0的認(rèn)證流程比OAuth1.0更簡單。只需要三步:
A、引導(dǎo)用戶到授權(quán)服務(wù)器,請求用戶授權(quán),用戶授權(quán)后返回 授權(quán)碼(Authorization Code)
B、客戶端由授權(quán)碼到授權(quán)服務(wù)器換取訪問令牌(access token)
C、用訪問令牌去訪問得到授權(quán)的資源
更安全。token不再需要secret,并且也不再需要對token進(jìn)行加密。但OAuth2.0采用了https安全協(xié)議,在安全保障更勝一籌。
并且OAuth2.0第三方應(yīng)用不再接觸到用戶的帳號和密碼,用戶直接跳轉(zhuǎn)到新浪微博的認(rèn)證界面進(jìn)行登錄。第三方應(yīng)用僅獲取登錄成功之后的結(jié)果。從而保障了用戶帳號的安全。
但是OAuth2.0認(rèn)證在移動(dòng)終端的應(yīng)用上也存在一定問題。主要倒不是安全上的,而是用戶體驗(yàn)上的。跳轉(zhuǎn)到授權(quán)頁面在移動(dòng)終端上體驗(yàn)不好,授權(quán)流程相對復(fù)雜,導(dǎo)致授權(quán)的轉(zhuǎn)化率受到影響。因此,新浪微博結(jié)合新浪微博客戶端一起推出了它的第四代授權(quán)認(rèn)證:SSO認(rèn)證。
4、通過微博客戶端的SSO認(rèn)證。
SSO的全稱是Single Sign On,中文名是單點(diǎn)登錄。當(dāng)?shù)谌綉?yīng)用與新浪微博客戶端為互相信任的應(yīng)用系統(tǒng)時(shí),僅需要一次授權(quán)登錄就可以在一定期限內(nèi),不再重復(fù)登錄授權(quán)而不受限制地調(diào)用新浪微博Open API提供的各種服務(wù)。
這種授權(quán)方式與新浪微博客戶端緊密結(jié)合,當(dāng)用戶有登錄新浪微博客戶端時(shí),只需要一鍵授權(quán)就能完成授權(quán)流程,非常便捷。另外第三方應(yīng)用通過微博客戶端進(jìn)行授權(quán)認(rèn)證,不會直接接觸到用戶的賬號密碼,賬戶安全也能得到保障。
SSO是一種非常好的移動(dòng)終端認(rèn)證方式,并且利于本身客戶端的推廣。安全性和便捷性都不錯(cuò)。但由于SSO的基礎(chǔ)是客戶端和第三方應(yīng)用需要互相信任,而這個(gè)信任關(guān)系本身的安全性存在缺陷。因此就會出現(xiàn)其他非信任應(yīng)用能夠冒充信任應(yīng)用獲得授權(quán)認(rèn)證,從而對用戶的微博進(jìn)行操作的情況。這就是我們本文中將做進(jìn)一步闡述的內(nèi)容。
二、如何冒充信任應(yīng)用,獲取客戶端的授權(quán):
在Android應(yīng)用中使用過新浪微博SSO認(rèn)證的朋友們都知道,針對新浪微博的授權(quán),官方提供了較詳細(xì)的文檔和封裝得足夠簡單的SDK供大家使用。由于本文內(nèi)容與這些技術(shù)細(xì)節(jié)關(guān)系不大,所以在此就不做細(xì)述,不了解的朋友可以去新浪微博開放平臺的官網(wǎng)上了解相關(guān)內(nèi)容。
事實(shí)上,新浪微博對于信任應(yīng)用的認(rèn)證環(huán)節(jié)相當(dāng)?shù)厝酢>唧w來說只需要兩個(gè)關(guān)鍵信息:CONSUMER_KEY和REDIRECT_URL。
CONSUMER_KEY即第三方應(yīng)用在新浪微博開發(fā)平臺網(wǎng)站后臺申請到的APP KEY。
REDIRECT_URL即第三方應(yīng)用在后臺填寫的OAuth2.0的授權(quán)回調(diào)頁網(wǎng)址。
當(dāng)這兩個(gè)信息匹配時(shí),新浪微博就會認(rèn)為是對應(yīng)的第三方應(yīng)用發(fā)起了合法的請求。授權(quán)流程就會正常進(jìn)行。如果這個(gè)第三方應(yīng)用已經(jīng)在之前做過了授權(quán),那么它就可以直接獲取access_token,然后就可以操作用戶的微博了!
現(xiàn)在我們假設(shè):
1、用戶的Android手機(jī)已經(jīng)安裝了新浪微博客戶端并已經(jīng)登錄。(應(yīng)該95%以上的手機(jī)滿足此假設(shè)吧)
2、用戶曾授權(quán)過一些主流第三方應(yīng)用進(jìn)行微博分享操作。例如camera360、美圖秀秀、網(wǎng)易新聞等。(此假設(shè)應(yīng)該也有90%以上的用戶滿足吧)
3、用戶的新浪微博端只登錄了單用戶帳號。多用戶帳號在SSO授權(quán)時(shí)需要用戶手動(dòng)選擇帳號,所以需要人為干預(yù)。(此假設(shè)也應(yīng)該有90%左右用戶滿足吧)
在滿足前面三個(gè)條件的情況下,只需要我們再獲取到用戶曾經(jīng)授權(quán)過的第三方應(yīng)用的CONSUMER_KEY和REDIRECT_URL就可以通過官方的SDK調(diào)用,在不需要人為操作的情況下操作Android手機(jī)用戶的微博了!
于是我們的問題集中在了如何獲取第三方應(yīng)用的CONSUMER_KEY和REDIRECT_URL上。
很多朋友也許會認(rèn)為,CONSUMER_KEY和REDIRECT_URL對于SSO授權(quán)認(rèn)證系統(tǒng)的地位就相當(dāng)于非對稱加密算法的私鑰,屬于非常隱私的、應(yīng)該被保密起來的信息,我們?nèi)绾慰梢垣@取到呢?
這里需要注意的是,私鑰之所以安全,是因?yàn)樗俏锢砀綦x的。私鑰的信息理論上只存在于軟件發(fā)布商的單機(jī)上,任何發(fā)布到公眾的信息中都不包含私鑰信息。因此,除非特殊途徑(例如拿到軟件發(fā)布商的電腦把私鑰拷貝出來,或者軟件發(fā)布商頭腦發(fā)暈,把私鑰給發(fā)了出去),我們認(rèn)為私鑰信息是絕對安全的。
而CONSUMER_KEY和REDIRECT_URL是授權(quán)過程中需要的信息,因此把必須在軟件的運(yùn)行時(shí)出現(xiàn),因此這個(gè)信息從理論上來講是發(fā)布到公眾的信息。通過一系列逆向、靜態(tài)、動(dòng)態(tài)分析,我們可以獲取到這些信息。因此它是不安全的。
正巧,幾個(gè)月前閑暇之時(shí),曾對一些如今比較流行的Android應(yīng)用做過這方面的技術(shù)分析。自己通過逆向獲取到了這些應(yīng)用的相關(guān)信息,如下圖:
注:沒列出來的應(yīng)用并不證明沒有此安全問題。
這些應(yīng)用都是現(xiàn)在最為流行的一些應(yīng)用。為了不引起公眾影響,我對其中的關(guān)鍵信息進(jìn)行了適度的隱藏。
因此只要你曾經(jīng)授權(quán)這些第三應(yīng)用(以及其他第三方應(yīng)用),那么從理論上來說,軟件安全的攻方,就可以通過逆向獲取這些應(yīng)用的CONSUMER_KEY和REDIRECT_URL,通過官方提供的SDK,在你不知情的情況下,操作你的新浪微博帳號了。
三、新浪微博的下一代授權(quán)認(rèn)證方式:
針對目前SSO授權(quán)認(rèn)證安全缺陷的情況,新浪微博推出了下一代SSO認(rèn)證,即SSO2.0。
事實(shí)上SSO授權(quán)認(rèn)證從去年推出以來,這個(gè)問題很快就被發(fā)現(xiàn),如果不是現(xiàn)在推出了SSO2.0,我可能還會繼續(xù)憋著不說。畢竟破解不是關(guān)鍵,關(guān)鍵是推動(dòng)軟件安全不斷進(jìn)步。
在理解了現(xiàn)在的SSO授權(quán)認(rèn)證機(jī)制及其缺陷后,SSO2.0很好理解。SSO2.0主要就是為了防止非信任的第三方應(yīng)用冒用信任的第三方應(yīng)用的身份。既然CONSUMER_KEY和REDIRECT_URL本身的信息安全都無法保障了,那該如何防止?
這又回到了很早以前我曾討論過的如何防止應(yīng)用被破解的問題上,應(yīng)用的身份如何防止被冒名頂替?最簡便且理論安全的方法就是通過簽名對比認(rèn)證。而這正是新浪微博SSO2.0所采用的方式。
在新浪微博開放平臺網(wǎng)站后臺,對第三方應(yīng)用綁定包名和簽名。這樣當(dāng)非信任應(yīng)用采用信任應(yīng)用的CONSUMER_KEY和REDIRECT_URL進(jìn)行認(rèn)證請求時(shí),由于包名和簽名對應(yīng)不上,服務(wù)器和微博客戶端就會拒絕認(rèn)證通過,從而補(bǔ)上了SSO1.0的安全缺陷問題。
當(dāng)然,SSO2.0也不是絕對安全的,它也存在自身的薄弱環(huán)節(jié)。不過,這就不是本文的討論范圍了。