介紹
OAUTH協(xié)議為用戶資源的授權(quán)提供了一個安全的杠茬、開放而又簡易的標準韭脊。與以往的授權(quán)方式不同之處是OAUTH的授權(quán)不會使第三方觸及到用戶的帳號信息(如用戶名與密碼)奕短,即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權(quán)嚎货,因此OAUTH是安全的举农。oAuth是Open Authorization的簡寫。
OAuth認證原理
OAuth 2.0中有6種常用的授權(quán)類型:
-
Authorization Code
-
Implicit
-
Password
-
Client Credentials
-
Device Code
-
Refresh Token
本文只介紹其中的Authorization Code(授權(quán)碼模式),這也是目前國內(nèi)大部分廠商使用的模式
你可能之前并沒聽過OAuth這個詞,但一定已經(jīng)使用過它了
例如新浪微博這里就提供了多種第三方登陸,下面筆者以”用QQ號登陸新浪微博”這個實例來講解OAuth認證的原理
我們把”微博”稱作客戶端,”QQ”稱作服務(wù)端
點擊QQ登陸的圖標,用戶將被導(dǎo)向服務(wù)端的認證服務(wù)器
用戶在此選擇是否給予客戶端(微博)授權(quán),如果授權(quán),則客戶端將會獲得用戶在服務(wù)端(QQ)的昵稱,頭像和性別資料
先來看下這個URL
這其中有重要意義的參數(shù)有以下幾個:
-
client_id
客戶端標識,這個參數(shù)是和客戶端一一對應(yīng)的,這樣服務(wù)端才知道認證請求來自哪個客戶端.例如”101019034”代表的就是新浪微博這個客戶端
-
response_type
授權(quán)類型,上文已經(jīng)說了OAuth有多種授權(quán)類型.此處”code”代表使用的是Authorization Code(授權(quán)碼模式)
-
scope
申請的權(quán)限范圍
-
redirect_uri
重定向URI,用戶給予授權(quán)后,將會攜帶授權(quán)碼跳轉(zhuǎn)到此地址
-
state
這個參數(shù)是用來防御CSRF的,你可以將其理解為我們常用的”token”.這里它的使用和”token”也是一樣的
每次授權(quán)請求,客戶端都會生成一個state,并將其保存到cookie或session中.授權(quán)成功后,服務(wù)端原樣返回state,客戶端將其與cookie或session中的值進行比對
回到授權(quán)過程,如果用戶點擊了QQ頭像確認授權(quán)
認證服務(wù)器確認用戶身份后,會生成一個授權(quán)碼(code),然后將用戶導(dǎo)向之前redirect_uri指定的地址,并附帶上授權(quán)碼(code)和state
state的作用已經(jīng)說過是防御CSRF的,最終要的就是這個code了
客戶端收到授權(quán)碼(code)后,將其發(fā)送到服務(wù)端比對(這一步在客戶端后臺服務(wù)器完成,對用戶不可見)
如果比對結(jié)果一致,那么游戲結(jié)束
在這個請求中,比對結(jié)束后,生成了一個alt,并跳轉(zhuǎn)到了login.sina.com.cn域
驗證了alt后,就在.sina.com.cn域種上cookie了.
從這個登陸案例來看,只要攻擊者拿到了code參數(shù),那么就能劫持用戶的微博賬號.
有經(jīng)驗的攻擊者一定發(fā)現(xiàn)了,既然code參數(shù)會發(fā)送到redirect_uri參數(shù)指定的地址,那么只要讓redirect_uri跳轉(zhuǎn)到我們指定的地址,那么就能竊取code.
OAuth幾個案例
案例1 新浪微博登陸劫持
redirect_uri限制不嚴格,可跳轉(zhuǎn)到任意子域
雖然redirect_uri不能任意指定,但是微博的業(yè)務(wù)設(shè)定為了可以跳轉(zhuǎn)到任意weibo.com的子域下.
如果我們能在某個子域下的某個頁面引入外部資源(img,vedio的href屬性;script標簽的src屬性),再讓redirect_uri攜帶code跳轉(zhuǎn)到這個頁面,那么我們就能從referer頭里竊取到code.
你可能首先會想到XSS,但是現(xiàn)在XSS不是那么好找了,而且用在這里有點大材小用.其實只要我們能引入一個外部圖片就行了.
這種功能很常見,很多地方都允許插入在線圖片.
我在xxx.weibo.com域下的一個帖子里插入了一個在線圖片,圖片地址填ceye平臺地址.
然后修改redirect_uri為該帖子的地址.
然后把這個鏈接發(fā)給受害者,一旦他點擊頭像確認登陸,攜帶code的請求就會被導(dǎo)向到攻擊者引入了外部圖片的頁面.
頁面加載了img標簽后,code就會通過referer頭泄露出去.
上文已經(jīng)說過,只要攻擊者拿到code,那么發(fā)送給passport.weibo.com進行認證,就能劫持用戶的微博賬號了.
案例2-某廠登陸劫持 "案例2 某廠登陸劫持")案例2 某廠登陸劫持
redirect_uri嚴格限制,但目標域不安全
看了案例1,你可能會覺得應(yīng)該由xxx.weibo.com背鍋,如果嚴格限制redirect_uri跳轉(zhuǎn)到指定域,就不會由問題了.
這是在一次眾測遇到的一個案例,貌似還沒修復(fù),就不說名字了.
該廠允許綁定淘寶賬號進行第三方登陸,
并且嚴格限制了只能跳轉(zhuǎn)到a.xxx.com域下,所以上面那種隨便找個子域插入圖片的套路看來是不行了.
但不幸的是,我正巧的a.xxx.com域下找到一個XSS,
所以,我們能更方便的寫入img或者scritp標簽了,后面竊取code的方法和上面一樣,就不多說了.
案例3 360 OAuth服務(wù)端漏洞
攻擊OAuth服務(wù)端,一鍋端
通過上面2個案例,我們可以得出這樣的結(jié)論:
不僅要嚴格限制redirect_uri跳轉(zhuǎn)的域,而且要保證其跳轉(zhuǎn)到一個安全的域.
但是,人在廣東已經(jīng)….啊不對,人在家中坐,鍋從天上來.
360作為服務(wù)端為其它廠商提供了OAuth認證的功能,開發(fā)者可以在360應(yīng)用開發(fā)平臺進行申請.
人家不僅提供了詳細的開發(fā)文檔,還給開發(fā)者弄了個調(diào)試工具.
理論上呢,redirect_uri是開發(fā)者自己填的,為了安全,只能是某個安全的域名.
但是,360為了便于開發(fā)者進行登陸調(diào)試,把”openapi.#”這個域名設(shè)置成了所有應(yīng)用的合法回調(diào)地址.
那么openapi.#這個域的安全性直接影響到所有客戶端.
不幸的是,我又在openapi.#下找到一個XSS,
所以,又能快樂的竊取到code了,并且影響了所有使用360賬號登陸的應(yīng)用.
總結(jié)
關(guān)于OAuth認證,還有其它的授權(quán)類型以及各種漏洞有待探索.
對于本文提及的授權(quán)碼模式,其中的redirect_uri參數(shù)應(yīng)該有以下遞進式的限制:
- 跳轉(zhuǎn)到專門的認證服務(wù)器域名
- 跳轉(zhuǎn)到該域名下某個確定的頁面
- 確保該頁面是安全的(無法引入外部資源)
參考
https://tools.ietf.org/html/rfc6819
原文:
https://03i0.com/2018/04/01/OAuth回調(diào)參數(shù)漏洞案例解析/