from:http://www.oauthsecurity.com/
這篇文章講了OAuth 和 OpenID容易出現漏洞的一些地方。不管是程序員還是黑客,閱讀它都會對你大有裨益。
就OAuth本身而言有一套很嚴謹的結構,但是很多開發者在部署AOuth的時候因為疏忽產生很多安全隱患,這些隱患如果被攻擊者利用,是很難防御的。
現在很多大網站,都存在OAuth安全隱患,我寫這篇文章的原因也是希望大家意識到由OAuth配置不當所引發的安全問題,和警示開發人員要小心處理關于OAuth的問題。
這篇文章并沒有闡釋OAuth的具體工作流程,想了解的話可以看他們的官網。
此文建議配合另外一個文章來看,包括烏云上很多實際案例:《OAuth 2.0安全案例回顧》
這是一種比較常見的攻擊手法,其實就是一種CSRF攻擊。
平臺返回code到事先設定好的回調url,SITE/oauth/callback?code=CODE
,之后客戶端把code連同client credentials 和 redirect_uri一起提交換取access_token。
如果客戶端沒有部署 state這個參數來防止CSRF攻擊,那么我們就可以通過CSRF輕易地把我們提供的賬號和受害者的賬號綁定。
如下圖所示,很多網站都提供使用社交賬戶登錄的功能。
防范方法:在把用戶的數據提交給提供者網站的時候,附帶一個隨機數,在連接返回時,沿著這個隨機數是否改變。
State fixation bug:(state可變漏洞):在omniauth中一些遺留代碼會導致state被修改,它使用 /connect?state=user_supplied代替了隨機數。 一些開發者把state拿來做其他的用途,導致他失去了防止CSRF的功能,一個工整的解決方式可以用JSON Web Token as state。
在會話固化攻擊中,攻擊者會初始化一個合法的會話,然后誘使用戶在這個會話上完成后續操作,從而達到攻擊的目的。
如果我們訪問一個用戶綁定的鏈接,比如/user/auth/facebook,這個鏈接通常會返回 一個附帶用戶信息的url,其中uid代表了攻擊者的id最終這個id將和受害者用戶綁定。
修復: 確認每一條綁定社交用戶的鏈接都擁有合法的csrf_token,最好使用post代替get。
Facebook駁回了這個CSRF漏洞的修復建議,很多庫中仍包含這一漏洞。所以不要奢望平臺方總是能給與你可靠的數據。
OAuth 的文檔清楚的寫出了,平臺方應該檢查redirect_uri是否被篡改。但我們通常懶得去檢查它。
這使得很多平臺方在這里產生了安全隱患,Foursquare (reported), VK (report, in Russian), Github (could be used to leak tokens to private repos)
攻擊的方式很簡單,尋找一個XSS漏洞,搞糟一個鏈接把redirect_uri修改為你自己的地址。當受害者訪問這個鏈接時,就會把leaking_page?code=CODE發送到你的指定地址。
這樣你就可以使用這個泄露的授權碼,在真實的redirect_uri上面登錄受害者的用戶了。
修復方法:可變的redirect_uri的確會產生風險,如果你非要用它,在access_token創建的時候驗證它是否被篡改。
這個漏洞被媒體稱之為"covert redirect" ,但是這并不是一個新的漏洞。
利用它的前提是需要有一個可以修改的redirect,之后吧response_type替換為token或者是signed_request。302重定向會附帶#后的信息,而攻擊者只需要通過js截取即可。
修補方式:在app setting中建立redirect_uri白名單。
這個漏洞也被稱為 One Token to Rule Them All.它通常發生在,手機和客戶端app上。
當用戶吧一個ring提交到一個他想登陸的網站時,一個惡意的網站管理員就可以通過這個ring登陸這個用戶正在使用的其他網站。
修補方式:在接受用戶提交的access_token之前,檢查他是否符合client_id。
client credentials其實并沒有那么重要,你所能做的就是取得auth code,然后手動得到一個access_token。
使用靜態redirect_uri,可以防止這種安全隱患。
OAuth1.0和OAuth2.0的主要區別就是向平臺傳輸參數的方式不同。在1.0中,客戶把所有參數傳遞給平臺,然后直接得到access_token。所以你可以誘使用戶訪問provider?request_token=TOKEN在授權完成后用戶會被重定向到client/callback?request_token=SAME_TOKEN如果這個TOKEN是我們事先生成的,那么我們就可以復用這個TOKEN.
這不是一個服務端的bug,通常它被用來釣魚,比如這個案例(FYI, Paypal express checkout has this bug)
有些平臺本身在其他平臺獲取賬號,同時也為其他用戶提供服務。通常他們都需要將url重定向到第三方網站,token在這樣的鏈條中很容易泄露
Facebook -> Middleware Provider -> Client's callback
而且這個問題基本無法修復。
facebook的解決方法是在callback url后面加上#= 防止其夾帶數據。
如果允許設置子目錄,下面是一些目錄遍歷的技巧
/old/path/../../new/path
/old/path/%2e%2e/%2e%2e/new/path
/old/path/%252e%252e/%252e%252e/new/path
/new/path///../../old/path/
/old/path/.%0a./.%0d./new/path (For Rails, because it strips \n\d\0)
code經過get傳輸的時候會存在于log文件中,平臺應該在使用或者過期之后刪除它們。