OAuth 1.0 协议学习

时间:2024-04-07 08:07:56

OAuth是一种开放的协议,为桌面程序和web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。

OAuth中的定义

  • Service Provider: 允许通过OAuth访问的web app,比如云存储服务
  • User: 拥有Service Provider账户的人
  • Consumer: website or app, 通过OAuth访问Service Provider,例如:云打印
  • Protected Resource:Service Provider的用户数据,例如用户保存在Service Provider上的照片
  • Consumer Developer:实现Consumer的个人或组织
  • Consumer Key: app申请接入OAuth时从OAuth服务商获得,用于在Service Provider中标识自己
  • Consumer Secret: 与key对应
  • Request Token: Consumer用来获取用户授权,并交换Access Token的值
  • Access Token: Consumer用来代表User获取Protected Resource
  • Token Secret: Consumer用来确定Token所有权的密码

请求URLs

  • Request Token URL: 获取未授权的Request Token服务地址;
  • User Authorization URL: 为Consumer访问获取用户授权的服务地址;
  • Access Token URL: 用授权的Request Token换取Access Token的服务地址;

部分参数

  • oauth_consumer_key: app申请接入OAuth时从OAuth服务商获得的Client ID
  • oauth_consumer_secret:oauth_consumer_key对应的**
  • oauth_signature_method: OAuth向三个URL请求时的数字签名方法
  • oauth_signature:数字签名
  • oauth_timestamp: 请求时间戳
  • oauth_nonce:随机字符串,用与防止请求重放攻击
  • oauth_version:可选字段,默认1.0

OAuth认证过程

OAuth认证是用户在不共享凭证的前提下与Consumer共享Protect Resource的过程。OAuth使用Service Provider提供的Token代替用户凭证请求用户Protected Resource。
OAuth 授权分三步完成:
- 1,Consumer 获取未授权 Request Token
- 2,User 授权Request Token
- 3,Consumer 将Request Token替换为Access Token

1,获取未授权Request Token

Consumer向Service Provider请求未授权Request Token。这个Token的目的是获得用户授权,并且只能用来获取Access Token,获取未授权Request Token流程如下:

1.1 Consumer访问Service Provider的Request Token URL,请求信息必须签名并且包含以下字段:

  • oauth_consumer_key
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version:可选
  • 附加参数

1.2 Service Provider Issues an Unauthorized Request Token

Service Provider确认签名及Consumer key。如果通过,生成一个Request Token和Token Secret,通过HTTp返回Consumer。Service Provider确保Request Token在用户授权前不能交换Access Token。返回信息:

  • oauth_token
  • oauth_token_secret
  • 附加参数

2,获取用户授权

Consumer在获得用户授权之前不能使用Request Token。获取用户授权的过程如下:

2.1 Consumer将用户导向Service Provider

Request Token需要获得用户授权,为此Consumer需要访问User Authorization URL,并包含以下参数:

  • oauth_token:可选,未授权Request Token,也可用户手动输入
  • oauth_callback:可选,Consumer指定一个URL,当授权成功后,Service Provider将用户重定向到该URL

Consumer构造请求URL并通过用户浏览器重定向到该地址,如果Consumer无法自动重定向,需要告知用户如何手动访问该地址。

2.2 Service Provider任重用户并获取许可

Service Provider验证用户身份并询问用户是否授权。OAuth不指定Service Provider如何鉴定用户,但定义了必须的步骤:

  • Service Provider询问用户许可前需要验证用户身份,可能要求用户先登录
  • Service Provider向用户展示Consumer申请访问的资源、权限等。这些信息在申请Consumer时由Consumer Developer注册。
  • 用户必须授权或否决服务提供方允许Consumer代表用户访问受保护资源。一旦用户否决,Service Provider不得允许Consumer访问受保护资源。

Service Provider根据Consumer key展示Consumer信息时,必须告知用户此信息是否可靠,展示方式不做特殊指定。

2.3 Servicve Provider将用户导向Consumer

如果用户授权,需要告知Consumer Request Token已被授权。否则告知Consumer Token被收回。

如果Consumer请求时指定了oauth_callback,则Service Provider将请求导向该URL,并包含参数:oauth_token

如果请求时不指定oauth_callback,Service Provider需要告知用户手工通知Consumer完成授权的方法。

3,授权Request Token换取Access Token

Consumer请求Access Token URL,用Request Token换取Access Token。过程包含以下步骤:

3.1 Consumer请求Access Token

Consumer 访问Access Token URL,请求需签名,且包含以下信息:

  • oauth_consumer_key
  • oauth_token
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version

获取Access Token不包含附加参数,以确保令牌相关信息都是之前用户确认时存在的。

3.2 Service Provider提供Access Token

Service Provider确保:

  • 请求签名验证通过
  • 请求令牌未被交换过
  • 请求令牌与Consumer key符合

如果成功,Service Provider生成Access Token,并通过HTTP响应,应包含以下参数:

  • oauth_token
  • oauth_token_secret
  • 附件参数

Consumer需要保存Access Token及**,用来签署Protected Resource的访问。

4,访问Protected Resource

Consumer获取Access Token和**之后,可以访问Protected Resource,访问资源的参数文档由Service Provider提供,一般包含:

  • oauth_consumer_key
  • oauth_token
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version

安全

OAuth 1.0设计完成后发现了协议存在漏洞,并在后来1.0a中修复了该漏洞。但是使用过程中发现开发人员不能很好的实现协议要求的数字签名,从而导致存在大量漏洞。于是IETF重新设计了OAuth2.0,新协议不需要签名,但是与1.0版本不兼容。

oauth_consumer_secret和oauth_token_secret应用于签名中,可以oauth_consumer_secret, oauth_token_secret编码后用”&”连接作为key。

会话固化攻击

这是OAuth 1.0中存在的漏洞:
- 1,攻击者登录他在一个合法Consumer站点的账户,获得一个request token
- 2,利用trap site让受害者授权这个request token
- 3,之后针对callback的不同,有几种不同的处理方法:
- 如果Provider站点对第二步(请求用户授权)中的callback没有限制,那么攻击者可以利用trap site将callback设为自己的站点,然后通过这个callback判断受害者何时完成授权。等到受害者授权后,攻击者继续完成获得受害者的access token
- 其他的情况下(使用预定义的静态callback、没有callback由用户手工完成授权),那么攻击者和受害者之间进行竞争,当攻击者恰好在受害者授权和访问Access Token URL的间隙访问Access Token URL,那么攻击者就获得了受害者的access token

回顾协议,攻击者要访问Protected Resource,除了Access Token之外,还要有正确的签名。签名依赖consumer_secret才和oauth_token_secret和加密算法。其中consumer_secret可能通过反编译等方式获取。OAuth服务商的签名设计普遍不规范,给攻击者提供了方便。

修补

1.0a版本对漏洞进行了修补。
OAuth 1.0 协议学习

  • 1.0协议中callback在oauth认证的第二步(请求用户授权)中通过url参数设置并明文传输。新的1.0a协议中,callback作为oauth第一步(获取request token)的参数(oauth_callback),并参与到签名过程。此外当没有callback时,callback值必须设为oob(out-of-bound)。
  • Service Provider在返回request token的同时,返回一个oauth_callback_confirmed参数,其值为true,表示Provider支持1.0a协议。
  • 用户完成授权后,Provider在redirect到callback时,提供一个新的oauth_verifier参数(无法被猜测的随机字串),该参数会被用在request token换取access token的过程中。如果callback值为oob,那么Provider需要提供页面显示oauth_verifier参数值。而Consumer可以引导用户将这个参数值填入适当位置,来完成授权。

原理

  • 通过预先指定callback,并将其作为request token的一部分,可以避免攻击者假造callback的情况
  • 通过oauth_verifier参数,可以避免攻击者和受害者竞争访问callback页面的问题。(在使用预定义静态callback或者无callback的情况下,callback无法对攻击者保密。但因为攻击者无法获知oauth_verifier参数值,因此无法换取access token)

参考

OAuth 1.0
OAuth 1.0核心
OAuth 2.0
OAuth 2 Simplified
OAuth 1.0会话固化攻击
OAuth 2.0隐蔽重定向漏洞