Oauth2.0安全问题浅谈

大家如果对Oauth还不是很了解可以先看下这篇文章https://www.cnblogs.com/maoxiaolv/p/5838680.html

我这篇博客主要是总结一下安全测试过程中遇到Oauth2.0有哪些可能存在的漏洞,以及如何去测试。

Oauth2.0协议流程

(A)用户打开客户端以后,客户端要求用户给予授权。(比如说你登陆淘宝,但是不想注册淘宝账户,于是淘宝说你可以用QQ登陆哟,于是说好,这个时候淘宝将你引导至QQ的认证服务器)

(B)用户同意给予客户端授权。(这个时候你在手机上弹出是否授权,你点击是,这个时候会返回一个授权码给淘宝,为什么是返回给淘宝呢?因为第一步中发送的认证服务器中会带有一个重定向url,是淘宝自己的)

(C)客户端使用上一步获得的授权,向认证服务器申请令牌。(淘宝拿着这个授权码再去找认证服务器)

(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。(淘宝取人授权码无误后,发放accesstoken令牌)

(E)客户端使用令牌,向资源服务器申请获取资源。(淘宝拿着令牌就可以访问QQ资源服务器)

(F)资源服务器确认令牌无误,同意向客户端开放资源。(QQ资源服务器对比令牌无误后开放资源)

 

上面有些细节没讲(例如url一般是怎样的),但不影响我们的测试。

这里还要科普两个知识点:

1.并不是什么网站都可以想QQ要授权的,比如说淘宝想和QQ搞这Oauth,必须先在QQ(服务提供商)那里进行注册,淘宝需要提供以下三个东西

  1)应用程序名称

  2)应用程序网站

  3)回调URL

  注册完成后,QQ会给淘宝两个东西

  1)Client ID (用于在构建上面B步骤中的请求url,这样QQ才知道是什么网站在找我要授权吧)

  2)Client Secret(也是淘宝要给QQ的东西,Client ID谁都知道可以伪造,这东西只有QQ和淘宝知道,至于是怎么给的还不知道)

2.上面的C、D两个步骤属于授权过程,Oauth2.0提供了四种授权模式

  • 授权码授权模式(Authorization Code Grant)
  • 隐式授权模式(Implicit Grant)
  • 密码授权模式(Resource Owner Password Credentials Grant)
  • 客户端凭证授权模式(Client Credentials Grant)

  

 Oauth2.0协议本身没有什么问题,只是开发人员在实现授权过程中没有严格安装协议规定来,可能会导致一些常见的问题

 其中主要是前三种可能存在问题,先以授权码授权模式为例将下流程吧:

 

 

授权码模式:

A)用户访问客户端,客户端将用户引导向认证服务器。

(B)用户选择是否给予客户端授权。

(C)如用户给予授权,认证服务器将用户引导向客户端指定的redirection uri,同时加上授权码code。

(D)客户端收到code后,通过后台的服务器向认证服务器发送code和redirection uri。

(E)认证服务器验证code和redirection uri,确认无误后,响应客户端访问令牌(access token)和刷新令牌(refresh token)。

请求示例

A)步骤:客户端申请认证的URI(淘宝请求QQ)  

https://www.example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read&state=xxx

 参数说明:

  response_type:授权类型,必选项,此处的值固定为"code"
  client_id:客户端的ID,必选项
  redirect_uri:重定向URI,必选项
  scope:申请的权限范围,可选项
  state:任意值,认证服务器会原样返回,用于抵制CSRF(跨站请求伪造)攻击。

(C)步骤:服务器回应客户端的URI(用户点击授权后,QQ引导用户访问A步骤中指定的重定向url,并带着授权码和state)

https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xxx

 参数说明:

  code:授权码,必选项。授权码有效期通常设为10分钟,一次性使用。该码与客户端ID、重定向URI以及用户,是一一对应关系。
  state:原样返回客户端传的该参数的值。

(D)步骤:客户端向认证服务器申请令牌(淘宝带着接收到C步骤中的请求后,用授权码发送下面的请求去找QQ认证服务器要token)

https://www.example.com/v1/oauth/token?client_id=CLIENT_ID&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

参数说明:

  client_id:表示客户端ID,必选项。
  grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
  code:表示上一步获得的授权码,必选项。
  redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。

注意:协议里没有提及client_secret参数,建议可以使用此参数进行客户端的二次验证。

(E)步骤:响应(D)步骤的数据

复制代码
    {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }
复制代码

 参数说明:

  access_token:访问令牌,必选项。
  token_type:令牌类型,该值大小写不敏感,必选项。
  expires_in:过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  refresh_token:更新令牌,用来获取下一次的访问令牌,可选项。
  scope:权限范围,如果与客户端申请的范围一致,此项可省略。

使用场景
    • 授权码模式是最常见的一种授权模式,在oauth2.0内是最安全和最完善的。
    • 适用于所有有Server端的应用,如Web站点、有Server端的手机客户端。 
    • 可以得到较长期限授权。

 

授权码授权模式常出现的安全问题是A步骤中,由于开发者没有严格按照协议来,请求中没有带上state,可能造成账户劫持的问题。正常情况下,淘宝先生成一个state并放在session中,然后再A步骤中的请求中带上state,QQ返回url带有授权码和state的链接给淘宝,淘宝这个时候需要在后台对比这个state是否和session中的一样,用来防止csrf攻击(这里将的有点啰嗦,实际上就是csrf嘛)。如果开发者在开发中没有使用state,我们也应该怎样测试呢?

1.确认A步骤中是否带有state,如果没有该参数则存在漏洞

2.准备AB两个账号,A是攻击者,B是受害者,两个都登陆的情况下,当然是不同的浏览器下喽(这里有个场景限制,就是绑定账户的地方才有,比如说我有各淘宝账户,但是要记住账号密码登陆很麻烦,我将他绑定到QQ,以后就可以直接用QQ登陆啦)

3.A点击绑定QQ,然后用打开burp抓包,点击授权,一步一步forward,知道遇到请求中带有授权码的请求,复制该请求后drop掉,因为code一般都是一次性的

4.拿去B账户的浏览器中打开(实际攻击中就是csrf嘛),会发现B账户绑定了A账户的QQ,以后A就可以用自己的QQ登陆B的淘宝了。

 

 

隐身授权模式:

A)客户端将用户引导向认证服务器。

(B)用户决定是否给于客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端指定的”重定向URI",并在URI的Hash部分包含了访问令牌。

(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。

(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。

(F)浏览器执行上一步获得的脚本,提取出令牌。

(G)浏览器将令牌发给客户端。

请求示例

(A)步骤:客户端发出请求

https://www.QQ.com/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read&state=xxx

 参数说明 

  response_type:授权类型,此处的值固定为"token",必选项。
  client_id:客户端的ID,必选项。
  redirect_uri:重定向的URI,必选项。
  scope:权限范围,可选项。
  state: 任意值,认证服务器会原样返回,用于抵制CSRF(跨站请求伪造)攻击。

(C)步骤:认证服务器响应客户端的请求url

https://www.example.com/callback#access_token =ACCESS_TOKEN&state=xyz&token_type=example&expires_in=3600&state=xxx

 参数说明

  access_token:访问令牌,必选项。
  token_type:令牌类型,该值大小写不敏感,必选项。
  expires_in:过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
  scope:权限范围,如果与客户端申请的范围一致,此项可省略。
  state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

使用场景
    • 适用于所有无Server端配合的应用
    • 如手机/桌面客户端程序、浏览器插件。
    • 基于JavaScript等脚本客户端脚本语言实现的应用。

 

这里主要讲下隐式授权和授权码授权的区别:

两者主要是应用场景不同,授权码授权模式中淘宝是有自己的server端的,也就是说淘宝有自己的账户,只是想和QQ绑定而已。而隐式授权模式适用于比如说QQ自己的其他服务,比如英雄杀这种网页游戏,假设它自己有没有单独的server端,那么就可以使用隐式授权模式找QQ的其他服务要授权(这里有点说不清楚哈,大家意会,其实也不一定是QQ自己的其他服务,比如说我自己开了各三国杀的网站游戏,我不想要自己的服务器端,因为用户可能不想麻烦再注册账户,那么我用隐式授权模式实现QQ的开发的Oauth服务,这样用户就可以直接用QQ的账户登陆啦)

说完大家就可以发现一个问题就是,隐式授权模式可能就不存在账户劫持的问题了,因为我(三国杀)都没有账户你怎么劫持呢?但是这里有个其他的问题:

这是上面A步骤和C步骤发送的两个请求

A   https://www.QQ.com/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read&state=xxx
C   https://www.example.com/callback#access_token =ACCESS_TOKEN&state=xyz&token_type=example&expires_in=3600&state=xxx

C步骤中的请求链接实际上来源A请求中的redirect_uri参数(用于指定重定向的链接),最为关键的地方是C请求中带有access_token,那么实际场景就是当state参数不存在的时候又可以进行csrf攻击了,伪造redirect_uri就好了,但正常情况下
QQ至少会对redirect_uri的域名做校验吧,所以不能随便重定向,需要找到受信任的网站下的xss漏洞,然后重定向获取劫持access_token即可
可以发现隐式授权如果存在问题一般是指服务提供商没有做好redirect_uri的校验,同时呢开发人员也没有加上state参数。


密码模式授权:这个没什么好说的,就是需要用户输入QQ的账号密码。判断是否存在漏洞就是看下有没有爆破漏洞



最后我还想说下sso(单点登陆的问题),sso和Oauth还是有区别的,sso主要是指比如我说登陆企业的OA后,我在OA里面再登陆企业邮箱啊、jira啊、wiki啊等等都不用再输入账号密码了,这就是单点登陆。
sso存在的问题主要是盗取access_token后登陆他人账户,原因主要没有对redirect_uri做校验:
场景一:和上面Oauth隐身授权模式的攻击手法一样,厂商只对域名做了校验,我们找到白名单中的域名下的xss漏洞进行利用就好了
场景二:厂商没有做任何校验,这里和Oauth有些区别,sso不同的公司实现其他可能都有些不同,根据开发者的安全意识而异,所以可能对redirect_uri没有任何校验,这样利用起来就方便很多了,可以直接跳转到www.evil.com,同时这里还可以尝试javascript:alert(1)进行xss



不能在写了,早上来就写这个,工作还没干呢

转载于:https://www.cnblogs.com/jinqi520/p/10075471.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值