大家如果对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)  

  1. 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)

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

参数说明:

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

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

  1. 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)步骤的数据

  1. {
  2. "access_token":"2YotnFZFEjr1zCsicMWpAA",
  3. "token_type":"example",
  4. "expires_in":3600,
  5. "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  6. "example_parameter":"example_value"
  7. }

参数说明:

  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)步骤:客户端发出请求

  1. 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

  1. 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步骤发送的两个请求

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

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

Oauth2.0安全问题浅谈的更多相关文章

  1. Zabbix4.0安装浅谈

    一.此篇文章存在意义 针对超级小白,大神绕过 在zabbix官网https://www.zabbix.com/download里,需要数据库,但是并没有指导小白的我们如何安装数据库,此文章包含了Mys ...

  2. 0基础浅谈反射型xss(2)

    0x1:回顾前文疑惑“先闭合,在构造” 上一篇,我们说到了xss的一个触发精髓,“先闭合,在构造”,对于前面的先闭合,我们来简单的解释一下:   首先说,为什么要闭合? 因为HTML标签都是成对出现的 ...

  3. 0基础浅谈反射型xss (1)

    0X1:在学习xss之前,先快速学习相关的HTML代码 1.  <input>标签 文本域用法: <input  type="text" /> Type的作 ...

  4. [C#]6.0新特性浅谈

    原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...

  5. 浅谈Android Studio3.0更新之路(遇坑必入)

    >可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...

  6. 浅谈linux中shell变量$#,$@,$0,$1,$2,$?的含义解释

    浅谈linux中shell变量$#,$@,$0,$1,$2,$?的含义解释 下面小编就为大家带来一篇浅谈linux中shell变量$#,$@,$0,$1,$2的含义解释.小编觉得挺不错的,现在就分享给 ...

  7. 浅谈[0,1]区间内的n个随机实数变量中增加偏序关系类题目的解法

    浅谈[0,1]区间内的n个随机实数变量中增加偏序关系类题目的解法 众所周知,把[0,1]区间内的n个随机.相互独立的实数变量\(x_i\)之间的大小关系写成一个排列\(\{p_i\}\),使得\(\f ...

  8. Spring5.0源码学习系列之浅谈BeanFactory创建

    Spring5.0源码学习系列之浅谈BeanFactory创建过程 系列文章目录 提示:Spring源码学习专栏链接 @ 目录 系列文章目录 博客前言介绍 一.获取BeanFactory主流程 二.r ...

  9. Spring5.0源码学习系列之浅谈循环依赖问题

    前言介绍 附录:Spring源码学习专栏 在上一章的学习中,我们对Bean的创建有了一个粗略的了解,接着本文浅谈Spring循环依赖问题,这是一个面试比较常见的问题 1.什么是循环依赖? 所谓的循环依 ...

随机推荐

  1. Codeforces Round #443 (Div. 1) C. Tournament

    题解: 思路挺简单 但这个set的应用好厉害啊.. 我们把它看成图,如果a存在一门比b大,那么a就可以打败b,a——>b连边 然后求强联通分量之后最后顶层的强联通分量就是能赢的 但是因为是要动态 ...

  2. Base64 加解密

    import java.io.UnsupportedEncodingException; import org.apache.tomcat.util.codec.binary.Base64; /** ...

  3. LCA最近公共祖先

    不会 准备研究一波!!! #include<bits/stdc++.h> ; using namespace std; vector<int> g[maxn]; ][maxn] ...

  4. Python 中文(大写)数字转阿拉伯数字(转)

    # constants for chinese_to_arabic CN_NUM = { '〇' : 0, '一' : 1, '二' : 2, '三' : 3, '四' : 4, '五' : 5, ' ...

  5. 多线程处理list

    package com.zhx.web.invoice.service; import java.util.*; import java.util.concurrent.Callable; impor ...

  6. mysql 正则表达式问号

    MySQL 中,用正则表达式匹配?,需要使用两个转义字符   \\? 因使用一个被坑了很久.

  7. ISP PIPLINE(零) 知识综述预热之光学概念篇

    1.光学成像关系如下:这是我看到最清晰的易懂的数学关系图 2.上面的知识了解完,camera应用的知识就是Autofocus技术,自动对焦 马达的起始位置一般在焦距处,由上面光学数学关系可知,焦距处可 ...

  8. JS this用法详解

        随着对js的深入学习和使用,你会发现它里面包含了很多令人困惑的机制,比如对象.闭包.原型链继承等等 1.this是啥? 简言之,this是JavaScript语言中定义的众多关键字之一,它的特 ...

  9. Intellij IDEA导入eclipse项目配置jdk、tomcat到浏览器正常访问

    转发自:博客园---Lindp(大佬写的甚好) 以下是转发的正文 intellij idea中文资料网上比较少,对于eclipse的项目如何导入intellij idea也没有完整的说明,本人在这里整 ...

  10. swift中单例类的创建

    1.最经典的 class TheOneAndOnlyKraken {     static let sharedInstance = TheOneAndOnlyKraken()     private ...