縱觀帳號互通發展史,能夠發現OAuth比起其它協議(如OpenID)更流行的緣由是,業務雙方不只要求帳號自己的認證互通(authentication;可理解爲「我在雙方的地盤姓甚名誰」),而是更須要雙方業務流的受權打通(authorization;可理解爲「我在雙方的地盤上可作什麼」),由於後者才能產生實際的互惠互利。javascript
2013年將過大半,有關OAuth的討論確有冷卻的趨勢,這源於在商業價值上該協議的使用愈來愈趨於理性;而OAuth 2.0在國內的實施也已經成熟,「第三方登陸」已經規模化。在這個時刻進行安全問題回顧,也許能夠爲將來相似協議的安全實施作一個參考。在此以前,captain pysolve《淺談OAuth安全(OAuth Security)》(2012年11月)和pnig0s《OAuth Security》(2012年12月),均進行了OAuth歷史和漏洞回顧;而Eran Hammer於2012年7月撰寫的著名文章《OAuth 2.0:通往地獄之路》,則以協議制定參與者的身份,在原理上闡述OAuth 2.0爲何「在大部分開發者手中會容易出現不安全的實現結果」。本文主要從被攻擊的資源分類角度,結合wooyun等披露案例對OAuth 2.0實施過程進行分點回顧,也在總體上反映國內開放平臺的歷史關注度。爲簡化責任說明,本文主要有以下角色:平臺方、應用方、用戶。本文可能有錯誤,敬請指正。html
OAuth 2.0的標準在去年(2012年)10月份總算塵埃落定:RFC 6749 The OAuth 2.0 Authorization Framework(中文翻譯點此https://github.com/jeansfish/RFC6749.zh-cn)和RFC 6750 The OAuth 2.0 Authorization Framework: Bearer Token Usage(中文翻譯點此https://github.com/jeansfish/RFC6749.zh-cn)。相比OAuth 1.0的實踐式總結,OAuth 2.0更像是一種框架式指引,這其中主要的特色有:html5
從業務出發點來說,制定OAuth 2.0協議的最大動力之一,是但願用一個協議適應多個業務場景受權,即須要既能知足傳統客戶端受權場景,又要知足無服務器參與的受權場景,甚至還有手機應用受權場景等等等等。java
而這種拉大業務場景的結果,通常也意味着薄弱點的增多,這是由於在場景複雜化的狀況下,開發方容易考慮不周、或者對應用方的相關安全指示不足,應用方也容易錯誤使用應用場合,而協議對這些場景也沒有更加深刻的指引。另外它也可能致使場景之間的安全問題產生了交叉,一些原本屬於潛在威脅,很容易經過場景轉換變成了顯性漏洞。對於擅長「由點到面」的攻擊者來講,如今只須要針對常見薄弱點(尤爲是受權認證流程中的薄弱點)就有可能攻擊成功。android
OAuth 2.0的rfc定義了幾種場景受權模式,並容許平臺方自行擴充,本文討論的有:ios
用戶在平臺方受權頁面登陸後,跳轉的redirect_uri中,參數段(如http://cakkback_url/?code=aaaaa&state=ssss)帶code參數;此時應用須要再次向平臺方的指定接口(通常爲獲取Access Token接口)發起請求,用code參數換取access token。git
這是OAuth 1.0中幾乎惟必定義過的業務場景,主要用於傳統客戶端和有服務器參與的網站受權。github
圖:rfc6749 第4.1節Authorization Code Grant流程圖web
圖:Authorization Code Grant常見的實現模式:以網站應用爲例sql
用戶在平臺方受權頁面登陸後,跳轉的redirect_uri中,uri片斷(如http://cakkback_url/#access_token=aaaaaa&uid=aaaaa)直接帶access token。
這種場景不驗證應用的有效性,主要用於無應用方服務器參與的純瀏覽器javascript/HTML5交互。
圖:rfc6749 第4.2節Implicit Grant流程圖
圖:Implicit Grant常見的實現模式:以無應用服務器的瀏覽器插件爲例
應用直接向平臺方的指定接口(通常爲專用的XAuth登陸接口;或者爲獲取Access Token接口)發起請求,直接用用戶名和密碼獲取Access Token。
圖:rfc6749 第4.3節Resource Owner Password Credentials Grant流程圖
圖:Resource Owner Password Credentials Grant常見的實現模式:以傳統客戶端應用爲例
從具體技術實現來說,OAuth 2.0爲了讓平臺方能夠以最小的業務改造代價整合已有資源,對於許多方面並不做強制要求,這其中一個核心精神,就是將應用層簽名流程簡化(甚至去除),並依賴傳輸層加密(TLS)。在業界的實踐中,這種精神被轉化爲無綁定token(Unbounded tokens)和無記名token(Bearer tokens) :OAuth 2.0中既不存在Access token secret等簽名專用參數,也放棄以請求參數爲基礎生成一個簽名hash值的作法;整個api通信過程在表面上和瀏覽器訪問https網站很相像,惟一不一樣的是cookies換成了access token。雖然標準有推薦相似OAuth-HTTP-MAC的簽名流程提案,但在實踐中並不待見。
這種簡化和不做強制要求,提升了平臺方和應用方的安全編碼要求——在沒有協議保障安全下(OAuth 1.0就是靠強制簽名),雙方(尤爲是應用方)須要自行實施可以相互配合的安全方案,才能保障整個OAuth 2.0的使用全過程,均是出於用戶自身意願的受權。但問題是,開發廣泛有匱乏安全意識的客觀狀況,對「認證」和「受權」之間的區別也難以細究,更遑論平臺方和應用方之間的安全不對等和相互推諉,這就使得靠開發保障安全的美好想法落空。
此處以新浪微博api爲例給出兩個協議的區別:
【HTTP, Sina weibo OAuth 1.0a】
GET /users/show/123456.json?oauth_consumer_key=【應用APP KEY】&oauth_nonce=【OAuth隨機值】&oauth_signature=【查詢參數+應用APP SECRET+Access Token Secret三者共同進行簽名後的值】&oauth_signature_method=HMAC-SHA1&oauth_timestamp=【請求時間】&oauth_token=【Access Token】&oauth_version=1.0a HTTP/1.1 Host: api.t.sina.com.cn
【HTTPS, Sina weibo OAuth 2.0】
Host: api.weibo.com GET /2/users/show.json?uid=123456 HTTP/1.1 Authorization: OAuth2 【Access Token】
OAuth 2.0的安全實施問題,有很是可能是落在攻陷應用方的帳號體系上,這是由於應用方的水平良莠不齊且不可控,其安全意識更弱,所以攻擊者會挑選最薄弱地帶攻擊。
漏洞頻率:常見
責任方:應用方(主要)、平臺方(無或次要)
wooyun案例:
2012-08-24 WooYun: 淘網址sina oauth認證登陸漏洞
2013-01-14 WooYun: 啪啪任意進入他人帳號(OAuth 2.0無綁定token問題)
2013-01-19 WooYun: 金山快盤手機客戶端任意進入他人快盤帳號
漏洞成因和建議修復方案:
不管是OAuth 1.0仍是OAuth 2.0,應用場景最多的就是第三方登陸(帳號打通),其中關鍵步驟,在於當應用方經過平臺方的Access token獲取接口獲得受權信息(Access Token、uid、expire_time等)後,如何將其做爲參數匹配到本身應用方的帳號,而後自動登陸(或自動註冊)。針對這個流程常見的攻擊之一是修改受權信息,若是後續的匹配處理邏輯出現紕漏(好比不當參數選擇或無驗證機制),那麼就有可能致使任意登陸到任一應用方帳號的嚴重漏洞。
圖:攻擊Access token數據的薄弱點
在OAuth 1.0仍是Authorization Code Grant一統天下的年代,因爲主要用於服務器網站應用,這個問題頂多算是潛在問題,畢竟若是要改受權信息,只能操做服務器或者在服務器所在網站arp——都入侵到那種地步了有啥不可能。不過是世事無絕對,當年已經有開放平臺提早實現了Implicit Grant場景,而後有網站錯誤使用了這種模式,經過javascript獲取裏面的uid/access token,而後再提交給網站直接進行登陸;結果因爲這些受權信息能夠被攻擊者輕易地截包修改,形成安全問題——淘網址的漏洞,就是這麼來的。
而OAuth 2.0在對待手機、平板之類應用的受權的問題上,通常都傾向於返回access token;而後由應用將access token上報給服務器,以進行應用自身的帳號認證登陸。這種場景的變化致使被篡改的難度大大下降(簡單的驗證方法是使用fiddler2進行截包篡改),但許多手機開發者、乃至手機背後的服務器api開發者並無意識到,結果錯誤選擇了受權信息做爲參數(好比單純選擇uid)、或者沒有對受權信息(access token)進行來源驗證,從而致使這類漏洞大爆發。
圖:手機開發者引入OAuth 2.0後,常犯的任意登陸到應用方帳號嚴重漏洞成因
解決這類漏洞的關鍵點主要靠應用方,但平臺方也必需要參與:
(1)應用方須要認真考慮在整個自動登陸/自動註冊的過程當中,平臺方返回的受權信息(尤爲是access token和uid)會否被用戶篡改;若是任一個受權信息都會被篡改,那麼在服務器中必須再次使用平臺方給出的access token驗證接口,驗證該access token是否爲指定來源應用所頒發,同時使用該access token驗證接口給出的uid,而不能使用可能被篡改的原uid值。
若是應用方已經收到該漏洞攻擊的影響,則須要對對全部已存入的綁定access_token進行覈查,發現access_token中的平臺方uid和綁定的平臺方uid不一致、非自身客戶端應用appkey受權的access_token、過時access_token等異常狀況均須要所有撤消,要求這些異經常使用戶從新受權登陸。
(2)平臺方須要開發access token驗證接口,接收參數爲access token等,返回結果應包括頒發的應用來源(通常是appkey)、uid、過時時間等。同時平臺方應針對受影響開發者,發佈安全公告和指引,說明易受攻擊和使用此接口的場景。
漏洞頻率:常見
責任方:應用方(主要)、平臺方(若是沒有配合應用方的csrf防護,則爲主要;不然無)
wooyun案例:
2012-11-10 WooYun: 優酷網存在帳號被劫持風險
2013-01-07 WooYun: 大麥網存在賬號被劫持風險
2013-03-01 WooYun: 美麗說oauth漏洞可劫持帳號
漏洞成因和建議修復方案:
有關應用方csrf劫持的問題,不得不提2012年11月份的一場大討論。那場討論的漏洞場景主要是使用Authorization Code Grant的應用(網站居多),主要的漏洞緣由是redirect_uri中的code參數沒有和當前客戶端的狀態綁定,攻擊者能夠經過發送預先獲取好的code參數到受害者電腦,致使致使受害者當前登陸的應用方帳號被綁定到攻擊者指定的平臺方(如微博)賬號上。當時我寫了篇文章《小議OAuth 2.0的state參數——從開發角度也說《互聯網最大規模賬號劫持漏洞即將引爆》》,詳細建議用state參數防護這種csrf攻擊,此處再也不重複。
圖:針對code參數的Authorization Code Grant攻擊;以及和rfc6749的流程圖關係
應用方要預防這種csrf劫持帳號,加入state參數是比較簡單的通行方法。根據rfc6749 章節10.12,該值既不可預測,又必須能夠證實應用(client)和和當前第三方網站的登陸認證狀態存在關聯(若是存在過時時間更好)。一種簡單的方法是:隨機算一個字符串,而後保存在session,回調時檢查state參數和session裏面的值。
而平臺方也要在回調時,支持應用方的state參數(固然若是容許redirect_uri參數中帶應用方本身的防csrf參數,其實也能夠)。
但嚴格來說,僅有state參數,其實還不夠,還須要結合3.3提到的防護手段。
漏洞頻率:常見
責任方:應用方(主要)、平臺方(主要?次要?)
wooyun案例:
暫無
其它案例:
webstersprodigy,2012-5-9,Common OAuth issue you can use to take over accounts:
http://webstersprodigy.net/2013/05/09/common-oauth-issue-you-can-use-to-take-over-accounts/
(csrf stackexchange(應用方) + csrf facebook(平臺方) = 繞過state參數 + 將受害者的stackexchange帳號綁定到攻擊着指定的facebook帳號)
漏洞成因和建議修復方案:
加入state參數是否就意味着沒有問題?好比認可,去年我在文章中僅關注僅關注state參數確實很片面,甚至是違反了「安全是一個總體」的原則,人爲割裂了整個受權過程的總體分析,掩蓋了其它問題乃至攻擊角度:state參數確能有效保護受權過程當中是當前用戶的惟一真實操做,可是發起受權前呢?受權後呢?國外的這個案例給了很好的答案(該案例在zone上有討論):
(1)facebook(平臺方)存在登陸漏洞,能夠被csrf
若是平臺方能夠被xss、或者沒有xss但其登陸流程有漏洞能夠被csrf(好比登陸表單沒有referer保護),那麼就可讓受害者的電腦登陸到攻擊者指定的平臺方帳號。這個的做用是幹啥?別急,往下看。
圖:webstersprodigy csrf facebook登陸的poc
(2)stackexchange(應用方)csrf發起綁定請求
回想一下做爲一個普通用戶,在應用方(stackexchange)綁定平臺方(facebook)帳號的過程:用戶到stackexchange綁定頁面,提示未綁定facebook,此時固然會點擊「開始綁定」。那麼有沒有想過,「開始綁定」這個動做,實際上是沒有作csrf保護的?這正是應用方(包括我本身)長期以來忽視的一個問題——在應用點擊發起綁定受權時,並不等於向平臺方發起受權請求啊,它必需要作一些邏輯判斷(包括生成state參數)後才能跳轉到平臺方的受權頁面……
圖:webstersprodigy展現應用方的綁定頁面
所以,結合上面提到的facebook(平臺方)能夠csrf登陸,攻擊者首先讓受害者電腦登陸到指定的facebook帳號,而後再csrf stackexchange(應用方)綁定請求,那麼就能夠達到劫持應用方賬號的目的了。而這兩點成因,和state參數所防護的攻擊場景有必定區別,因此徹底能夠bypass掉。
圖:webstersprodigy的csrf應用方綁定請求poc
圖:webstersprodigy的完整攻擊流程圖
@渥村萬濤 當年的評論,更能說明有關csrf劫持應用方賬號這類問題的本質,只惋惜我醒悟得太遲:「其實, 這個漏洞的根本緣由, 是違反了RFC6749, 沒有任何CSRF保護, 而不是沒有使用state參數 (state只是實現CSRF保護的一種). 根據RFC6749http://t.cn/zlTZyo6state是推薦(SHOULD), 而不是必須(MUST). 但CSRF保護是MUST. 沒有用state, 不違反標準, 但沒有CSRF保護, 則違反」(發表於2012-11-10 12:50)
而返回到這個漏洞,「安全是一個總體」再一次體現——只有平臺方和應用方的共同努力,纔可能修補徹底。不過各位都懂的,對於這種有多個責任方問題的漏洞,這幾乎不可能…...
針對平臺方的建議:
(1)檢查全部登陸頁面和登陸流程,防止出現登陸漏洞。
好比在存在登陸入口的頁面(尤爲是在具備sso登陸功能的頁面上)上,強制進行referer和一次性token驗證,以防止被csrf登陸。
又好比檢查全部登陸相關的流程,防止出現漏洞。如下是一些例子:
2013-02-19 WooYun: 豬八戒網不用帳號密碼登陸任意帳號
2013-03-18 WooYun: 飯統網登陸任意帳戶漏洞
(2)檢測會否可以對賬號異地登陸有反應並採起措施。
不過若是出現定向攻擊,這彷佛沒啥用。
針對應用方的建議:
(1)作好發起綁定平臺方帳號(新浪微博、QQ空間、人人網等等)、解除綁定等等等等諸如此類的綁定相關動做的csrf防禦。這是整個開發界一直以來忽視的點。
(2)在綁定頁面顯示綁定的平臺方暱稱、uid等信息等,防止用戶沒法自查綁定信息。
(3)綁定和解綁時,通知用戶。
漏洞頻率:少見
責任方:應用方(主要)
wooyun案例:
2012-03-14 WooYun: 5sing.com藉助第三方鏈接可建立重複暱稱帳戶
漏洞成因和建議修復方案:
實際上這類漏洞和OAuth協議(或者說任何一個帳號互通登陸協議)沒有關聯,純粹是應用方設計的賬號體系邏輯存在問題。將其放在這裏主要是但願提醒應用方開發者,仔細審查帳號設計體系和實現方式,在使用平臺方的帳號互通時要留意對方賬號體系的不一樣點(在OAuth實現中,則主要體如今應用方帳號綁定和註冊中的代碼邏輯),避免出現重複賬號問題。
通過OAuth 1.0的洗禮,平臺方在安全上有了更多的認識,好比強制限定回調地址(較可能是驗證域名部分)以下降redirect_uri跳轉的範圍,強制access token有效期(甚至基本不提供refresh token之類的東西)以限制應用方的長時間資源佔用和濫用等。但業務場景的多樣化,使得攻擊者遊走在場景之間以點撕面;而平臺方則受制於防護成本到處受困(不管是來自自身仍是來自應用方)。
漏洞頻率:常見
責任方:應用方(主要或次要)、平臺方(主要或次要)
wooyun案例:
2012-04-15 WooYun: 人人網Oauth 2.0受權可致使用戶access_token泄露
2012-08-27 WooYun: 透過[新浪微博]官方來源調用API發表微博.無需client_sec
2012-09-20 WooYun: 無需client_sec可用QQ登陸平臺發表空間日誌等高權限操做(WooYun-2012-11314衍生)
2012-09-25 WooYun: QQ互聯開放平臺QQ登錄oauth受權接口能夠劫持access_token
2012-09-25 WooYun: 百度開放平臺oauth受權接口能夠劫持access_token
其它案例:
Egor Homakov,How we hacked Facebook with OAuth2 and Chrome bugs,2013-2-19:
http://homakov.blogspot.com/2013/02/hacking-facebook-with-oauth2-and-chrome.html
(利用OAuth 2.0 Implicit Grant特性 + Chrome bug獲取facebook的access token)
漏洞成因和建議修復方案:
有關Implicit Grant場景的討論,可見2012年9月撰寫的zone文章《從wooyun-2012-11314小議OAuth 2.0認證缺陷》。此處將一些關鍵點拿出來再討論。
Implicit Grant場景的特色是受權驗證時只須要client_id和redirect_uri這兩個參數做應用標識,返回的時候也就直接在uri片斷中返回access token。這個場景的提出,和客戶端(client-side)業務需求有着密不可分的關聯,典型例子就是無服務器參與的純javascript交互的瀏覽器插件、各類網站掛件。在這種業務下,客戶端難以保密雙secret(app secret,access token secret)也難以加密,所以乾脆將這些限制均進行簡化。
但Implicit Grant場景也在安全問題上深深地困擾着平臺方:
(1)因爲缺失了雙secret的簽名,api僅憑access token基本難以分辨應用請求來源
(2)絕大多數開放平臺經過Implicit Grant方式認證獲取的client-side access token,可用於服務器的api通信中(即權限等同於走Authorization Code Grant方式獲取到的server-side access token)
(3)各開放平臺因爲要實施諸如網站掛件之類的應用,常常會對本身開放平臺的中轉頁面或者跨域文件大開綠燈。也就是說redirect_uri會放行兩類域名:應用方本身的域名、平臺方本身指定的中轉域名。
(4)client_id(即應用appkey)和redirect_uri基本屬於公開信息。
以上困擾造就一種最多見且棘手的網站安全問題,那就是隻要合做方網站(最多見)、平臺方網站甚至是瀏覽器三者之一有任何一個xss,攻擊者無需知道app secret,就很容易xss獲取到access token,而後以此攻擊受害者的平臺方帳號。
另外一種困擾則是「當受權用於認證時的不當參數選擇或無驗證機制」所闡述的,既然api分辨不了應用請求來源,那麼只要掌握了A應用中受害者的access token,而且在B應用中的某些關鍵請求步驟中替換掉,那麼就有可能順利登陸到B應用的受害者應用方帳號。
第三種則是應用冒充,攻擊者只使上述公開參數用就能冒充成其它應用調出受權頁面,獲取到的access token能夠用於控制受害者的平臺方帳號。若是是高權限client_id,獲取到的access token顯然更有破壞力。
解決這個問題,rfc6749第10.16小節就只是語焉不詳的說須要額外的安全措施,這也反映了這種場景的防護難處。從實踐來看,有一種方法是必須的:平臺方必須對應用方的應用強制進行分類——即應用方在申請client_id(即應用appkey)時,須要選擇屬於哪類應用;平臺方再根據分類開放對應權限,而且進行特定的防護和監控措施,如下以手機sso登陸sdk進行分析。
漏洞頻率:常見
責任方:平臺方(主要)
wooyun案例:
2013-03-27 WooYun: 開放平臺單點登陸SSO方案設計缺陷致使釣魚風險
其它案例:
@囧虎張建偉,新浪微博Android客戶端SSO受權認證缺陷,2013-09-08:http://www.blogjava.net/zh-weir/archive/2013/09/08/403829.html
漏洞成因和建議修復方案:
圖:新浪微博開放平臺開發文檔移動應用SSO受權
手機應用sso登陸sdk,通常是指應用方使用該sdk後,當用戶點擊受權時,若是若是已經安裝了平臺方的官方手機應用,就會跳到那裏,由該官方應用代爲受權,免去從新輸入用戶名和密碼。
若是這其中有OAuth參與,就會發現各家的實現方式會有Implicit Grant的影子。在早期,應用在初始化sso sdk的時候,只須要client_id(即應用appkey)和redirect_uri便可發起受權請求。而這兩個參數基本是公開的;即使再加上client_secret,在反編譯/逆向後拿到手也是易如反掌(後面將闡述)。因此攻擊能夠進行應用冒充,獲取access token來控制用戶在平臺方的帳號。
平臺方一開始是着重防護受權頁面被僞造和重放攻擊(這也確實要作的),因此官方手機應用彈出的受權頁url是有參數簽名的,但這防護不了惡意使用client_id的問題。後來你們意識到進行手機應用的包名和簽名驗證,纔算比較好的解決了這個問題。不過在這裏要提醒,若是fallback機制不對(好比沒裝官方客戶端後的受權流程沒作好)、或者簽名對比機制自己就有漏洞,也可能會被繞過......
漏洞頻率:不常見
責任方:平臺方(主要)
wooyun案例:
2012-11-05 WooYun: 開心網android客戶端暴力破解漏洞,測試2000賬號,成功132個
其它案例:
2013-03-15,CCTV 2013年315晚會中「指控」高德地圖低版本「收集新浪微博用戶名和密碼」(後高德發表聲明否定):http://jingji.cntv.cn/2013/03/15/ARTI1363354929366253.shtml
漏洞成因和建議修復方案:
這是一個存在較大爭議的場景:在談判桌上,這是體現應用方公司和平臺方公司之間的實力角逐;在開發界裏,這是提高用戶體驗和轉化率的利好方法;在安全界中,倒是有着偷竊隱私和危害用戶的後門行爲。這個引發開發界和安全界爭論不休的東西,叫作XAuth,叫作Resource Owner Password Credentials Grant,又或者,叫作直接用平臺方用戶名和密碼獲取access token。
XAuth常見的目標業務有這兩種:(1)內部或自身官方應用的服務調用;(2)應用方的高級合做和深度整合。能夠說,XAuth表明着的高級受權認證,是平臺方對應用方最大的信任和合做。
但畢竟XAuth是由應用方代爲提交用戶名和密碼到接口,而繞過了平臺方自己的受權認證頁面,所以從安全來講,在沒法確保應用方能力信譽和安全情況的狀況下,難以保證用戶名和密碼不會被泄露。好比若是是網站類應用容許使用XAuth,按照深度整合的流程,通常都會設計成直接在應用方的網站上彈出代理登陸界面;用戶輸入平臺方帳號和密碼後,經過應用方服務器同步登陸到平臺方和應用方帳號。但這種設計流程,很容易在傳輸到應用方網站的過程、乃至在應用方服務器上就泄露了帳號密碼等敏感信息。手機類應用也可類比(參見高德低版本微博登陸流程)。
圖:常見的XAuth威脅
另一點,因爲XAuth的高級受權認證,限制一般會放得比較寬,這會致使常規登陸的保護流程在XAuth接口處失效,那麼攻擊者就能夠實施撞庫掃號攻擊。
然而徹底取消XAuth在業務上也並不現實,所以還必須立足在業務上提出切實的解決方法:
(1)對於外部合做方,最大限度取消且不開放XAuth的受權。對於由於合同緣由而致使沒法取消的狀況,須要增強監控。不得不說,2013 CCTV 315晚會但是幫了各大平臺方一把,使得在談判時,更有底氣說不開放XAuth了。
(2)內部應用同樣要劃分等級,無必要的應用一概禁止使用XAuth和內部接口。對於官方應用也不建議直接使用XAuth,最好走代理接口,緣由就在接下來討論的問題:高權限client_id等應用標識泄露。
漏洞頻率:常見
責任方:平臺方(主要)、應用方(次要或主要)
wooyun案例:
2011-06-01 WooYun: 金山毒霸微服務Oauth key泄露問題
2011-12-02 WooYun: 新浪微博可能致使用戶信息泄露的BUG
其它案例:
2013-03-08,John Leyden,Leaked: The 'secret OAuth app keys' to Twitter's VIP lounge:http://www.theregister.co.uk/2013/03/08/twitter_oauth_leaked_keys/
2013-4-10,Nicolas Seriot(HITBSECCONF2013 - AMSTERDAM),busing Twitters API and OAuth Implementation :http://conference.hitb.org/hitbsecconf2013ams/materials/D1T2%20-%20Nicolas%20Seriot%20-%20Abusing%20Twitters%20API%20and%20OAuth%20Implementation.pdf
(主要講述反編譯/逆向twitter官方應用獲取appkey和app secret(即client_id和client_secret),而後假冒官方應用使用;最後認爲將OAuth應用在傳統客戶端在根本上是錯誤的)
漏洞成因和建議修復方案:
致使高權限client_id和client_secret泄露的緣由有許多種,好比:
(1)官方或者高級合做夥伴的客戶端反編譯/逆向。這是許多有關OAuth能否使用在客戶端(不管是傳統桌面客戶端仍是手機客戶端等)的討論焦點之一。
(2)應用方源代碼泄露client_id和client_secret。
因爲Implicit Grant場景只須要client_id和redirect_uri就能夠形成破壞,所以僅泄露高權限client_id的緣由也須要考慮在內:
(1)代理接口錯誤設計。有些OAuth代理接口設計成傳遞client_id使用,結果被截獲。
(2)高級應用方(高級合做夥伴)使用了開放平臺掛件等。
泄露一般會帶來資源濫用的後果,常見的有:
(1)應用冒充:好比替換client_id和client_secret,將android手機應用裝成iphone客戶端,官方還不能封鎖,由於這個client_id表明官方應用,封了等於斷本身生意;又好比在Implicit Grant場景下,只使用client_id就能冒充成其它應用,從而控制受害者的平臺方帳號,此部分前面已經闡述。
(2)非合做數據挖掘:好比爬數據,又好比自動批量私信騷擾等。
(3)非正常的高級接口調用。
緩解client_id的泄露以及所帶來的資源濫用,如下解決方法能夠參考:
(1)應用方正確設計一組代理接口,在不泄露client_id和client_secret的狀況下對OAuth進行一層包裝。
例子爲新浪微博手機客戶端,它在後續的版本就不走OAuth流程,而是改成訪問代理接口,該代理接口的使用過程當中也不會傳遞client_id和client_secret。改造後,既解決了client_id和client_secret泄漏問題,又能夠更好地調整手機型號的判斷。
(2)平臺方從協議入手阻斷批量調用不一樣client_id。
例子爲騰訊開放平臺。因爲用戶關係是QQ的核心,因此騰訊爲反關係數據挖掘,對OAuth標準進行了一些改動,每一個client_id獲取的用戶openid(用戶QQ號碼轉化獲得的ID)均不同,這樣,就可以防止攻擊者批量調用不一樣client_id進行數據挖掘和用戶騷擾。
圖:騰訊開放平臺資料庫OpenAPI調用相關問題
不過要在這裏說明的是,實際上不管是學術研究、商業數據挖掘仍是垃圾信息發送者,其實他們根本就不會乖乖走OAuth,畢竟要濫用資源辦法實在是太多了,衆包爬頁面、客戶端插入都是方法。所以對平臺方來說,討論OAuth會否致使資源濫用可能並不重要,重要的是討論使用OAuth後可否遏制其它方面的資源濫用——畢竟OAuth訂立了一種和外界商業合做的態度和框架,那麼平臺方就能夠據此遏制這個框架外的未受權資源濫用。貌似和安全無關,扯遠了…...
(3)平臺方完善接口權限控制和行爲監測,發現異常進行處理和報警。
漏洞頻率:不常見
責任方:平臺方(主要)
wooyun案例:
2012-10-30 WooYun: 騰訊微博開放平臺openid、openkey截取
2013-04-11 WooYun: 搜狐微博OAuth2.0獲取Authorization Code過程隱患
漏洞成因和建議修復方案:
這一塊主要是由於對場景考慮不周致使的OAuth 2.0協議實施不全面。因爲本人沒有作過平臺開發,所以除了建議考慮場景以外,沒法給出更具體的分析和建議了。
如下內容並不是是OAuth協議獨有(甚至和OAuth無關),它只是反映了當前在實現api協議的時候共同面臨的問題,故歸到雜項。
漏洞頻率:常見
責任方:平臺方(主要)
wooyun案例:
(與主業務流脫節)
2012-11-24 WooYun: 繞過騰訊微博運營限制繼續發微博
(與主業務流錯誤整合混用)
2012-03-06 WooYun: 新浪微博開放平臺接口惡意利用漏洞可致使病毒傳播
2012-07-20 WooYun: 新浪微博加關注CSRF漏洞(已經氾濫)
2012-11-10 WooYun: 新浪微博安全漏洞,致使微博賬號被輕易盜用
2013-04-02 WooYun: 豆瓣API 2.0接口CSRF
漏洞成因和建議修復方案:
業務流失調問題並非OAuth協議獨有,全部存在多套業務流(尤爲是不一樣入口都可完成同一任務)的軟件開發都容易出現這類bug(進一步就是漏洞),它反映的是業務劃分沒有定式的難題。上面的案例就反映出api接口和主業務流(通常用在平臺方主站點)之間有着太多選擇問題:
一方面,api接口但願保持邏輯獨立性,以方便全平臺擴展;但若是api滯後於主業務流,那麼就會出現脫節現象。好比因爲開發計劃滯後,暫時只在主站限制了實名發微博,但api還沒上這個策略,那麼攻擊者就能夠直接用api繞過這個限制。
另外一方面,主業務流也但願將自身集成到api接口中,以確保全平臺策略一致性;但若是本着「不重複造輪子」,錯誤整合混用的話,那麼就會出現干擾問題。好比主站能夠用登陸cookies看成access token直接調用api接口,這就容易實施各類csrf攻擊。
解決業務流失調的關鍵仍是在於業務範圍大小範圍劃分以及服務粒度粗細(還有api粒度粗細)範圍劃分,這都須要平臺方內部數個(乃至數十個)業務流相關項目組的共同討論和配合執行。這個話題很是大,對架構師的要求較高。
漏洞頻率:常見
責任方:平臺方(主要)、應用方(主要)
wooyun案例:
(平臺方api接口問題)
2012-10-08 WooYun: 網易 Oauth 身份驗證機制存在 XSS
(平臺方api接口 + 平臺方sdk或應用方輸出過濾問題)
2012-06-05 WooYun: 」用qq登錄「api接口xss
(平臺方api配套系統問題)
2010-11-08 WooYun: 人人網某頻道XXS漏洞
2012-07-08 WooYun: 騰訊開放平臺儲存型xss漏洞
2013-04-28 WooYun: 優酷開放平臺 存儲型XSS腳本攻擊漏洞 成功劫持後臺
漏洞成因和建議修復方案:
因爲OAuth本質上是http服務,故不管是api接口自己仍是配套系統也會有諸如xss(常常出如今各類jssdk和網站掛件中)、csrf、sql注射、甚至ddos等等的安全威脅。其根源和解決(緩解)方法與傳統web安全在部分課題上基本一致,但也有一部分也存在差別,見雲舒有關cc攻擊的研究和PPT。
在這裏要特別提醒應用方和作官方SDK的平臺方開發人員,api傳遞回來的數據可能並無通過過濾,此時仍須要以「輸入不可信」的處理方法進行過濾。
漏洞頻率:常見
責任方:平臺方(主要?次要?)、應用方(主要?次要?)
wooyun案例:
2013-03-18 WooYun: 微信存非法記錄其餘網站帳號密碼行爲
(注意:該案例僅是webview自帶的自動記錄功能,claudxiao進行了分析和說明:http://blog.claudxiao.net/2013/03/android-webview-cache/
其它案例:
淘寶開放平臺,無線開放平臺開發要求「無線類應用受權必須走瀏覽器模式而非webview模式」,2013-9-12訪問和驗證:http://open.taobao.com/doc/detail.htm?spm=0.0.0.0.L44DxW&id=972
漏洞成因和建議修復方案:
手機開發中,瀏覽器控件通常用於在應用內嵌入網頁,以進行應用和網站之間的html5混合交互和提高用戶體驗。android和ios上通常指基於webkit引擎的WebView組件Windows Phone則有基於IE的WebBrowser控件(如下內容未對WP實證)。
有一些用戶沒法信任應用使用瀏覽器控件打開OAuth受權認證登陸頁面,其主要緣由有:
(1)沒法看到打開的url,容易被釣魚。
(2)瀏覽器控件可被注入應用的惡意js代碼,致使帳號被泄露等。
固然,最近大熱的WebView接口編碼不當致使任意代碼執行也不是不可能存在,不過從該問題的歷史討論來說,這個並非主要擔心緣由。
要讓用戶信任瀏覽器控件內的應用受權頁面,當前主要實踐模式都是平臺方開發交互性更加便捷的官方手機應用SDK(好比手機SSO SDK等),並在提交應用審查時要求使用官方SDK或者遵照相關開發要求。目前在國內最嚴格的是淘寶開放平臺,在無線開放平臺開發要求明確要求「無線類應用受權必須走瀏覽器模式而非webview模式(具體實現能夠參看兩種無線sdk下載包中的文檔)」,固然在前期這個舉措,使得淘寶有着較大壓力和遇到碎片化難題(討論見1、2、3)。
除了SDK和開發要求外,平臺方還有一個問題,那就是受權頁面自己如何防止瀏覽器控件和瀏覽器自動記錄功能(不管在手機仍是PC)。這個時候,autocomplete=off就要派上用場了。
漏洞頻率:常見
責任方:平臺方(主要?次要?)
wooyun案例:
無
其它案例:
《Why Eve and Mallory Love Android: An Analysis of Android SSL (In)Security》中文簡翻(附原文):http://zone.wooyun.org/content/1396
漏洞成因和建議修復方案:
因爲https比tls更加衆所周知,因此此處用https這個詞了。OAuth 2.0將安全性基本押寶在傳輸層加密上,因此https的安全問題也會影響到OAuth 2.0(或者其它協議)安全,但具體分析這個問題也是煩惱不斷。
一方面,https在網絡不穩定的狀況下容易出現超時。在2012年3月份@quaful 給了一個血淚教訓:「在手機上使用 https 協議要慎重。在北上廣深之外的中國廣大城市,有 20%~25% 的用戶都會遇到 https 鏈接困難。排查發現問題和接入點無關,信號和網絡不穩定致使 https 請求很難完成。」。
另外一方面,即便使用了https,因爲絕大部分應用的代碼不會去檢查證書,這就致使一旦遇到arp和中間人攻擊,基本game over。
因此在這個問題上各平臺方和應用方的解決平衡之道可謂是五花八門(好比其中一種是讓重要接口和流程走https,而其它仍是走回相似OAuth 1.0形式的http+請求參數簽名),雖然從理論上,讓任何OAuth 2.0流程都不走https的方法,都有違反協議所訂立的安全前提嫌疑。
而對於一些重要接口的應用開發,在使用https的時候仍是建議開啓檢查證書的代碼(最好進行證書鎖定),不過帶來的問題是很差調試,此時就是各開發者進行debug log能力大比拼了。
如下錯誤不表明OAuth 2.0沒有,只是說你們吸收教訓,已經開始少見。
(1)平臺方受權頁面的csrf
2012-02-15 WooYun: CSRF致使微博應用自動受權
2012-07-20 WooYun: 第三方APP強制新浪用戶OAUTH受權漏洞
2012-12-03 WooYun: 網易開放平臺第三方應用oauth強制用戶受權漏洞
(2)OAuth 1.0 session fixation
攻擊根源:回調url參數oauth_callback可被攻擊者控制,致使任意跳轉。
攻擊過程:
(A)攻擊者從應用方預先獲取帶REQUEST TOKEN參數的受權認證頁面url,但並不跳轉,而是記錄下原來的oauth_callback參數,並將其替換成攻擊者的url。
(B)受害者訪問該惡意構造的受權認證頁面url後,使用本身的平臺方帳號進行受權。完畢後平臺方根據oauth_callback,連同REQUEST TOKEN等參數,指示受害者瀏覽器跳轉到攻擊者的url。
(C)攻擊者打時間差,搶先訪問原來的oauth_callback參數,至此成功登陸到受害者的應用方帳號上。整個過程不須要知道APP SECRET和REQUEST TOKEN SECRET,也能夠bypass應用方的csrf防護。
防護方法:
後續規範OAuth1.0a和RFC 5849中,明確規定oauth_callback參數須要加入生成REQUEST TOKEN的簽名中;而且平臺方在返回回調url時,帶上不可預測的oauth_verifier參數。相關詳細資料請參考:http://sakinijino.com/archives/1208
和OAuth 2.0的比較:
因爲OAuth 2.0沒有簽名,故平臺方的開放平臺應用管理界面上,有「綁定域名」或者「回調url」設置選項,不符合這些設置的會在受權頁面上報錯(好比invalid_redirect_uri);oauth_verifier參數則被code參數取代。
案例:
2010-11-03 WooYun: Sina 微博OAuth 提供者存在session fixation attack漏洞
2011-02-18 WooYun: 新浪微博應用URL跳轉
2011-04-29 WooYun: 街旁網第三方登陸劫持漏洞
2013-07-01 WooYun: 圖蟲網第三方認證缺陷致使能夠劫持賬號
2013-07-23 WooYun: 團800oauth缺陷可能導用戶賬號被劫持
(3)沒有考慮全面的協議實現之OAuth 1.0版
2012-12-02 WooYun: 139郵箱OAuth 1.0標準協議設計缺陷
2012-12-04 WooYun: 天涯開放平臺第三方應用oauth冒名受權漏洞