OAuth2.0相关
OAuht2.0我们接触的并不少,在我们登陆第三方应用的时候 用到了OAuth2.0,如下场景
比如我们要登陆一个网站,登陆的时候可以用QQ账号,微信账号,微博账号等进行登陆,这里的登陆就用到了OAuth2.0
什么是OAuth2.0
开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用.目前广泛使用的版本是OAuth 2.0.
协议模式
1 |
|
现在普遍用的都是授权码模式
角色
resource owner
资源所有者,能够允许访问受保护资源的实体resource server
资源服务器,即服务提供商存放受保护资源,与授权服务器可以是同一服务器,也可以是不同服务器。比如使用微博账号来登陆微博博客,就可认为资源服务器就与授权服务器为同一服务器。如果用微博账号去登陆知乎,资源服务器就与授权服务器为不同服务器client
客户端,代表向受保护资源进行资源请求的第三方应用程序authorization server
授权服务器,在验证资源所有者并获得授权成功后,将发放访问令牌给客户端
授权过程
1 | +--------+ +---------------+ |
拿一个实例来说,比如现在我用QQ来登陆知乎
请求的url为
1 | /oauth2.0/authorize?scope=get_user_info,get_info,add_t,add_pic_t,get_other_info,get_fanslist,get_idollist,add_idol,add_share&state=424d6e5461427a5958506474634c59417634643231636533423336666c4e7171&redirect_uri=https://www.zhihu.com/oauth/callback/qqconn&response_type=code&client_id=100490701 |
此时,我是resource owner
,提供资料的QQ服务器是resource server
,知乎的Web端是client
,QQ授权服务器是authorization server
这里,我们请求的URL里出现了一些字段,下面解释一下
client_id
:必须,客户端标识,这个参数是和客户端一一对应的,这样服务端才知道认证请求来自哪个客户端,比如这里的100490701就代表知乎客户端scope
:可选,请求资源(授权)范围state
:可选,可理解为token。防御CSRF,每次授权请求,客户端都会生成一个state,并将其保存到cookie或session中.授权成功后,服务端原样返回state,客户端将其与cookie或session中的值进行比对.redirect_uri
:可选,重定向url,将会携带授权码(下文的code)跳转到此地址response_type
:授权类型
当点击头像登陆时
这里返回的code字段才是最重要的,也就是上面说的授权码
验证成功在*.zhihu.com
种下cookie
OAuth2.0漏洞
攻击面
- redirect_uri绕过导致授权劫持
- state未设置导致CSRF
- scope越权访问
redirect_uri绕过导致授权劫持
从上面看到 在Location的时候code会携带在url中,于是如果redirect_uri
可以被恶意攻击者控制,在重定向到恶意网址时,会携带着code重定向到恶意网址,这样就造成了code的泄露
具体案例,参考sn00py师傅
sn00py师傅案例中出现了三种类型的授权劫持
- redirect_uri的子域可控
- redirect_uri严格限制,但目标域不安全(比如XSS,任意URL跳转)
- 直接攻击OAuth服务端
state未设置导致CSRF
看个例子
http://www.anquan.us/static/bugs/wooyun-2014-060493.html
出现漏洞的url是
1 |
|
在绑定微博账号时 可以看到,没有提供防御CSRF的state参数
于是当攻击者拿到攻击者自己账号OAuth2返回的code时,如
1 |
|
此时发给已经登陆的用户点击该连接,Web端就会将用户的账号和攻击者的微博账号绑定在一起,于是攻击者就可以利用微博登陆该用户的账号
scope越权访问
这里只举个例子来了解该漏洞
例如URL里的原本参数是这样的。Scope:read
。我截取这个请求然后修改一下为Scope:write
。如果我们可以修改文件,就说把原本可读的权限越权修改成了可写的权限