OAuth2.0原理与攻击面
文章目录
OAuth2.0协议原理
OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取部分用户数据。
OAuth2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。2012年10月,OAuth 2.0协议正式发布为RFC 6749 (Request For Comments 互联网标准文件,按编号排列)。
特点
- OAuth 的核心就是向第三方应用颁发令牌
- OAuth 2.0 规定了四种获得令牌的流程。你可以选择最适合自己的那一种,向第三方应用颁发令牌
应用
统一认证登陆、第三方账号绑定登陆
令牌与密码
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。
(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。
注意,只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。
OAuth的参与实体
至少有如下4个:
- RO (resource owner): 资源所有者,即用户,对资源具有授权能力。
- AS (authorization server):授权服务器,它认证RO的身份,为RO提供授权审批流程,并最终颁发授权令牌(Access Token)。
- RS (resource server):资源服务器,它存储资源,并处理对资源的访问请求。AS与RS可以是同一个服务器。
- Client: 第三方应用,它获得RO的授权后便可以去访问RO的资源。
OAuth2.0流程
第二步授权中,OAuth2.0提供多种授权模式。
前提:第三方应用现在授权服务器上申请client_id
、client_secret
重点来了
授权模式:
- 授权码模式 (Authorization Code Grant)
- 隐式授权/简化授权模式 (Implicit Grant)
- RO凭证授权/密码模式 (Resource Owner Password Credentials Grant)
- 客户端授权模式 (Client Credentials Grant)
授权码模式
这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
简化模式
适用于纯前端模式,所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
相比授权码模式,没有code
客户端模式
客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
密码模式
如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌
令牌刷新
令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 2.0 允许用户自动更新令牌。
具体方法是,授权服务器颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,客户端使用 refresh token 发一个请求,去更新令牌,不需要用户参与授权。
安全漏洞
OAuth2.0协议本身没有问题,出现安全问题的是协议在使用过程中的不规范,没有严格遵循协议的安全相关指导造成的。
本文总结的安全漏洞针对授权码模式和隐式授权模式
access_token未绑定用户
简化模式授权,access_token
暴露在前端且未进行严格检验。
举个栗子
A用户通过weibo登录hhh.com,验证weibo账号通过后跳回hhh.com并返回access_token
,
url:http://hhh.com/sina_login.php?redirect_url=http://hhh.com/#access_token=xxxxxxxxxxxxxx&remind_in=******&expires_in=******&uid=******
其中对认证用户身份的参数进行攻击:
- 替换uid,只要uid存在就可成功登录他人账号
- 替换access_token为B账号token,可登录B账号
OAuth 2.0在对待手机、平板之类应用的授权的问题上,一般都倾向于返回access token;然后由应用将access token上报给服务器,以进行应用自身的账号认证登录。这种场景的变化导致被篡改的难度大大降低,但许多手机开发者、乃至手机背后的服务器api开发者并没有意识到,结果错误选择了授权信息作为参数(比如单纯选择uid)、或者没有对授权信息(access token)进行来源验证,从而导致这类漏洞大爆发。
CSRF绑定劫持
授权码模式
前情提要:A用户在hhh.com拥有一个账号A,hacker希望用自己的weibo账号绑定A账号,从而登陆A账号进行恶意操作。
攻击流程:
- hacker在hhh.com注册一个账号B,点击绑定weibo,一路进行到返回code步骤
redirect_url=http://hhh.com/weibo_login&code=******
- hacker保存此url,并将此url发给A用户
- A用户点击url后将code发给认证服务器,继续进行hacker未完成的操作
- A用户得到
access_token
,但是此token携带的是hacker的weibo账号信息 - 账号A成功绑定了hacker的weibo账号
- hacker可以使用自己的weibo账号登录hhh.com愉快地操作了~
防御:
OAuth 2.0提供了state
参数用于防御CSRF。其实就是csrf_token
的一种形式,认证服务器在接收到的state
参数按原样返回给redirect_uri
,客户端收到该参数并验证与之前生成的值是否一致
redirect_url授权劫持
简化授权模式
简化授权模式场景的特点是授权验证时只需要client_id
和redirect_uri
这两个参数作应用标识,返回的时候也就直接在url片段中返回access_token
若未严格限制,简化授权模式结合xss可拿到access_token
http://hhh.com/oauth/grant?client_id=cd271e3051444285b8a18f1211a095cd&redirect_uri=http://xss_url/&response_type=token
授权过程中修改redirect_url
为一存在XSS的网站,当授权成功返回access_token
时跳到xss网站,攻击者通过referer
获得token
授权码模式
授权码模式access_token
不返回前端,但是code
返回,所以攻击者的目标是拿到code
,跟前面拿token一个流程
防御
严格限制url跳转
参考:
深入理解OAuth2.0&基于OAuth2.0第三方登录之GitHub实践
OAuth2.0协议详解
猴子都能看懂的简易图解
OAuth2.0漏洞案例
https://www.freebuf.com/articles/web/110757.html
https://gh0st.cn/archives/2018-02-12/1