Hu3sky's blog

About OAuth2.0

Word count: 1,252 / Reading time: 5 min
2019/02/22 Share

OAuth2.0相关

OAuht2.0我们接触的并不少,在我们登陆第三方应用的时候 用到了OAuth2.0,如下场景
比如我们要登陆一个网站,登陆的时候可以用QQ账号,微信账号,微博账号等进行登陆,这里的登陆就用到了OAuth2.0

什么是OAuth2.0

开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用.目前广泛使用的版本是OAuth 2.0.

协议模式

1
2
3
4
5
6
7
8

授权码模式(authorization code)

简化模式(implicit)

密码模式(resource owner password credentials)

客户端模式(client credentials)

现在普遍用的都是授权码模式

角色

  • resource owner 资源所有者,能够允许访问受保护资源的实体
  • resource server 资源服务器,即服务提供商存放受保护资源,与授权服务器可以是同一服务器,也可以是不同服务器。比如使用微博账号来登陆微博博客,就可认为资源服务器就与授权服务器为同一服务器。如果用微博账号去登陆知乎,资源服务器就与授权服务器为不同服务器
  • client 客户端,代表向受保护资源进行资源请求的第三方应用程序
  • authorization server 授权服务器,在验证资源所有者并获得授权成功后,将发放访问令牌给客户端

授权过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
+--------+                               +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+

拿一个实例来说,比如现在我用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:授权类型

当点击头像登陆时
1

这里返回的code字段才是最重要的,也就是上面说的授权码
验证成功在*.zhihu.com种下cookie
1

OAuth2.0漏洞

攻击面

  • redirect_uri绕过导致授权劫持
  • state未设置导致CSRF
  • scope越权访问

redirect_uri绕过导致授权劫持

从上面看到 在Location的时候code会携带在url中,于是如果redirect_uri可以被恶意攻击者控制,在重定向到恶意网址时,会携带着code重定向到恶意网址,这样就造成了code的泄露
具体案例,参考sn00py师傅

https://03i0.com/2018/04/01/OAuth%E5%9B%9E%E8%B0%83%E5%8F%82%E6%95%B0%E6%BC%8F%E6%B4%9E%E6%A1%88%E4%BE%8B%E8%A7%A3%E6%9E%90/

sn00py师傅案例中出现了三种类型的授权劫持

  • redirect_uri的子域可控
  • redirect_uri严格限制,但目标域不安全(比如XSS,任意URL跳转)
  • 直接攻击OAuth服务端

state未设置导致CSRF

看个例子
http://www.anquan.us/static/bugs/wooyun-2014-060493.html
出现漏洞的url是

1
2

https://api.weibo.com/oauth2/authorize?client_id=2892344974&redirect_uri=http%3A%2F%2Fwww.mafengwo.cn%2Fconnect_sync%2Fsina_v2_sync.php&response_type=code

在绑定微博账号时 可以看到,没有提供防御CSRF的state参数
于是当攻击者拿到攻击者自己账号OAuth2返回的code时,如

1
2

http://www.mafengwo.cn/connect_sync/sina_v2_sync.php?code=6e20eb6bfea2d969a8fa5435a5d106d5

此时发给已经登陆的用户点击该连接,Web端就会将用户的账号和攻击者的微博账号绑定在一起,于是攻击者就可以利用微博登陆该用户的账号

scope越权访问

这里只举个例子来了解该漏洞
例如URL里的原本参数是这样的。Scope:read。我截取这个请求然后修改一下为Scope:write。如果我们可以修改文件,就说把原本可读的权限越权修改成了可写的权限

参考

https://www.freebuf.com/articles/web/110757.html

https://03i0.com/2018/04/01/OAuth%E5%9B%9E%E8%B0%83%E5%8F%82%E6%95%B0%E6%BC%8F%E6%B4%9E%E6%A1%88%E4%BE%8B%E8%A7%A3%E6%9E%90/

CATALOG
  1. 1. OAuth2.0相关
    1. 1.1. 什么是OAuth2.0
    2. 1.2. 协议模式
    3. 1.3. 角色
    4. 1.4. 授权过程
    5. 1.5. OAuth2.0漏洞
      1. 1.5.1. redirect_uri绕过导致授权劫持
      2. 1.5.2. state未设置导致CSRF
      3. 1.5.3. scope越权访问
    6. 1.6. 参考