OAuth: How and Why?


  LI Daobing (盛大创新院)
    lidaobing@gmail.com
        @lidaobing
         July 2010
目录

为什么需要 OAuth?

OAuth 原理

OAuth FAQ
Sina 微博: 通过邮箱联系人邀请好友?




     要不要先改密码,再来输入?
       还是干脆直接放弃?
     新浪还可相信,小网站呢?
Facebook 做法




     1. 我确实是从 Facebook 点击过来的
     2. 确实是 Google 的网站
     3. 申请的权限仅限我的联系人
查看权限, 回收权限
             在整个过程中:
             1. 密码没有泄漏给 facebook
             2. 同时可以随时回收权限
更多情形

一个 twitter 客户端

一个手机上的 rememberthemilk 客户端

slideshare 想直接从你的 google docs 里导出 PPT

一个 Blog 客户端

...
需求再整理

前提
  我有一些数据储存在服务方A
  第三方客户端B想访问/修改我的数据

需求
  我想授权B访问我的数据,同时不暴露我的用户名和密码
  这种授权可以随时回收
  即使信息被窃听, 攻击者也无法伪造请求
  即使有恶意中间...
OAuth 能满足你的需求!
目录

为什么需要 OAuth?

OAuth 原理

OAuth FAQ
标准历史

2007-10: OAuth 1.0
2009-06: OAuth 1.0a
   主要解决一个安全漏洞 (后面有详细介绍)

2010-04: RFC 5849
   名词变更, consumer->client, ...
   ...
OAuth 词汇表

 三方
   客户端: client, 原称 consumer
   服务端: server, 原称 service provider
   资源所有者: resource owner, 原称 user (本文仍使用"
 ...
请求流程
详细数据流 (1/5)

 缩写
 CK: 客户端凭证key
 CS: 客户端凭证secret
 TK, TS: 临时凭证 key 和 secret
 AK, AS: 令牌凭证 key 和 secret (A 代表 access token)
详细数据流 (2/5)

0. 初始状态, 客户端持有 CK 和 CS
1. 用户发起授权操作: 用户点击位于客户端上的一个按钮, 发起授权
2. 客户端申请临时凭证:
   客户端向服务端发送 CK 和申请的授权(rights), 并用 CS...
详细数据流 (3/5)

5. 用户访问登录URL, URL中包含 TK 和 oauth_callback (回调URL)

6. 完成授权
如果用户没有登录, 服务端首先引导用户登录, 获得 server_user. 服务端根据
URL 中的...
详细数据流 (4/5)

7. 用户访问回调URL, 该URL 中包含 TK 和 verify_code
8. 客户端申请令牌凭证
   客户端通过 TK 拿到 TS 和 user_id, 首先判定此时的用户与申请TK时用户一
致, 然后向服务...
详细数据流 (5/5)

10. 客户端发起 API 请求
根据 API 文档准备数据, 加上 CK, AK, 使用 CS+AS 签名

11. 服务端返回 API 结果
根据 AK 从数据库中调出 [AS, CK, user_id, righ...
请求流程 (补上每步发送的数据)
签名范例

GET /photos?file=vacation.jpg&size=original HTTP/1.1 #请求 Path
Host: photos.example.net #请求 Host
Authorization: OAuth...
需求回顾
我想授权B访问我的数据,同时不暴露我的用户名和密码
用户名和密码都是在 A 服务器上输入的, 从未暴露
这种授权可以随时回收
在 A 服务器上随时可以回收
如果信息被窃听,数据不会有危险
API 请求需要用 CK+AK 来签名, 数据...
更多的安全细节

1. 客户端需要保存好 TS
2. TS 在服务端是明码保存的, 所以如果服务端被入侵, TS 可
   能会泄漏
3. 服务端用户登录页面必须是 HTTPS
4. 服务端展示客户端凭证密码的页面必须是 HTTPS 页面(很多...
本地客户端的

前面介绍的是网站客户端的情况,本地客户端跟网站主要有如下
几点差异

 没有回调 URL 的概念, 服务端直接在用户授权后显示对应的
 verify_code, 本地客户端提供一个输入框让用户来输入
 本地客户端需要一个保存CS...
目录

为什么需要 OAuth?

OAuth 原理

OAuth FAQ
为什么不用 HTTPS
Q: 前面提到的很多手段都是为了应对窃听和恶意中间人, 全部
用 HTTPS 不就行了么?
   一般情况下, 一个 IP+端口只能部署一套 HTTPS 密钥,也就
   是说没法玩虚拟主机了(因为在 Host 发送前T...
为什么使用 HMAC-SHA1
Q: HMAC-SHA1 需要计算两次 SHA1, 有必要么?
A: 签名是为了防止窃听者和恶意中间人伪造请求, 而其他更简单的签名
方法都存在安全风险
 1. 比如使用 sign = SHA1(key+data...
为什么需要 nonce 和 timestamp

A: 防止重放攻击 (Replay attack)
   一种重放攻击是把截获到的请求重发一次或多次, 对于 POST
   这种非幂等的方法会造成服务器端的数据错误。加入 nonce
   后...
1.0a 修复了什么Bug?
A: 1.0 下存在如下的一种攻击手法
1.0a 修复了什么Bug?

A: 1.0 下存在如下的一种攻击手法
 1. 存在两个用户: 攻击者和受害人, 存在一个客户端,这个客
    户端会把用户在服务端的权限通过 OAuth 绑定到本地帐号。
 2. 攻击者登录客户端, 在客户端...
1.0a 如何修复Bug?

 服务器应该提醒用户, 登录链接是否来自指定的网站。

 客户端应当确认,发起请求的用户和完成登录的是同一个用
 户 (避免在受害者访问 callback 时就完成绑定了)

 服务端会下发确认码, 攻击者无法构造...
OAuth 不做什么?
 只保护服务端,不保护客户端
   OAuth 只保证用户在服务端的数据不被非法访问或修改,
   但不保证客户端接收到正确的数据,恶意中间人可以修改
   返回的数据,当然这个也可以用签名来解决。
 不保护恶意浏览器/...
国内现有 OAuth 服务器的问题

 Douban
     仍在使用 OAuth 1.0
     客户端令牌展示页面没有加密
     密钥只有 64bit
 Sohu 微博
     每次认证时都要求用户输入密码, 容易造成用户麻痹, ...
Thanks for your attention!




            Q&A?
Upcoming SlideShare
Loading in …5
×

OAuth: How And Why?

5,312 views

Published on

Published in: Technology
0 Comments
12 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,312
On SlideShare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
118
Comments
0
Likes
12
Embeds 0
No embeds

No notes for slide

OAuth: How And Why?

  1. 1. OAuth: How and Why? LI Daobing (盛大创新院) lidaobing@gmail.com @lidaobing July 2010
  2. 2. 目录 为什么需要 OAuth? OAuth 原理 OAuth FAQ
  3. 3. Sina 微博: 通过邮箱联系人邀请好友? 要不要先改密码,再来输入? 还是干脆直接放弃? 新浪还可相信,小网站呢?
  4. 4. Facebook 做法 1. 我确实是从 Facebook 点击过来的 2. 确实是 Google 的网站 3. 申请的权限仅限我的联系人
  5. 5. 查看权限, 回收权限 在整个过程中: 1. 密码没有泄漏给 facebook 2. 同时可以随时回收权限
  6. 6. 更多情形 一个 twitter 客户端 一个手机上的 rememberthemilk 客户端 slideshare 想直接从你的 google docs 里导出 PPT 一个 Blog 客户端 ...
  7. 7. 需求再整理 前提 我有一些数据储存在服务方A 第三方客户端B想访问/修改我的数据 需求 我想授权B访问我的数据,同时不暴露我的用户名和密码 这种授权可以随时回收 即使信息被窃听, 攻击者也无法伪造请求 即使有恶意中间人, 攻击者也无法伪造请求
  8. 8. OAuth 能满足你的需求!
  9. 9. 目录 为什么需要 OAuth? OAuth 原理 OAuth FAQ
  10. 10. 标准历史 2007-10: OAuth 1.0 2009-06: OAuth 1.0a 主要解决一个安全漏洞 (后面有详细介绍) 2010-04: RFC 5849 名词变更, consumer->client, ... 时间戳不要求递增 小修改
  11. 11. OAuth 词汇表 三方 客户端: client, 原称 consumer 服务端: server, 原称 service provider 资源所有者: resource owner, 原称 user (本文仍使用" 用户") 三凭证 (凭证即两个随机字符串, 分别为 key 和 secret) 客户端凭证: client credentials, 原称 consumer key and secret, 客户端在服务端注册后获得 临时凭证: temporary credentials, 原称 request token and secret 令牌凭证: token credentials, 原称 access token and scret
  12. 12. 请求流程
  13. 13. 详细数据流 (1/5) 缩写 CK: 客户端凭证key CS: 客户端凭证secret TK, TS: 临时凭证 key 和 secret AK, AS: 令牌凭证 key 和 secret (A 代表 access token)
  14. 14. 详细数据流 (2/5) 0. 初始状态, 客户端持有 CK 和 CS 1. 用户发起授权操作: 用户点击位于客户端上的一个按钮, 发起授权 2. 客户端申请临时凭证: 客户端向服务端发送 CK 和申请的授权(rights), 并用 CS 签名 3. 服务端返回临时凭证, 服务端首先校验签名, 服务端生成一对 TK 和 TS, 把 {TK: [TS, CK, rights]} 放入 cache, 把 TK 和 TS 发送到客户端 4. 跳转至登录页面 客户端把 {TK: [TS, client_user]} 放入 cache, 使用 TK 和回调URL (oauth_callback) 构造出登录 URL, 发送一个 301 响应让用户跳转至登录 URL
  15. 15. 详细数据流 (3/5) 5. 用户访问登录URL, URL中包含 TK 和 oauth_callback (回调URL) 6. 完成授权 如果用户没有登录, 服务端首先引导用户登录, 获得 server_user. 服务端根据 URL 中的 TK 提取出 CK 和 rights, 展示客户端的详细信息以及申请的授权。 用户点击同意后, 服务端产生 AK, AS 以及一个 verify_code (一个随机字符 串), 更新 cache 为 {TK: [TS, CK, rights, AK, AS, verify_code, server_user]}, 根据URL中的 oauth_callback 和 verify_code 构造出新的回 调 URL。
  16. 16. 详细数据流 (4/5) 7. 用户访问回调URL, 该URL 中包含 TK 和 verify_code 8. 客户端申请令牌凭证 客户端通过 TK 拿到 TS 和 user_id, 首先判定此时的用户与申请TK时用户一 致, 然后向服务器发送 CK+TK+verify_code, 并用 CS+TS 签名 9. 服务端返回令牌凭证 服务端通过 TK 从 cache 取出 [TS, CK, rights, AK, AS, verify_code], 校验 CK 一致, verify_code 一致, 签名正确, 销毁 cache, 持久化 {AK: [AS, CK, user_id, rights]}, 返回 AK 和 AS
  17. 17. 详细数据流 (5/5) 10. 客户端发起 API 请求 根据 API 文档准备数据, 加上 CK, AK, 使用 CS+AS 签名 11. 服务端返回 API 结果 根据 AK 从数据库中调出 [AS, CK, user_id, rights], 校验 CK 及签名, 检验 访问的 API 是否在授权范围内, 使用 user_id 对应的数据支持 API, 返回结果 到客户端
  18. 18. 请求流程 (补上每步发送的数据)
  19. 19. 签名范例 GET /photos?file=vacation.jpg&size=original HTTP/1.1 #请求 Path Host: photos.example.net #请求 Host Authorization: OAuth realm="Photos", oauth_consumer_key="dpf43f3p2l4k3l03", #CK oauth_token="nnch734d00sl2jdk", #TK/AK oauth_signature_method="HMAC-SHA1", #签名方法 oauth_timestamp="137131202", #时间戳 oauth_nonce="chapoH", #nonce oauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D" #签名 1. 从客户端发送到服务端的每个请求都需要签名 2. 除了前面讲到的数据外, 需要额外加上 oauth_timestamp(时间戳) 以及 oauth_nonce, 用于防止重放攻 击 (后面有详解) 3. oauth_signature_method 用于指定签名方法, oauth_signature 为签名 签名细节参见 RFC 5849 3.4 节 , 简单来说就是把请求的内容拼接为字符串 (包括 GET/POST), 然后使用 对应的密钥签名
  20. 20. 需求回顾 我想授权B访问我的数据,同时不暴露我的用户名和密码 用户名和密码都是在 A 服务器上输入的, 从未暴露 这种授权可以随时回收 在 A 服务器上随时可以回收 如果信息被窃听,数据不会有危险 API 请求需要用 CK+AK 来签名, 数据窃听只能听到 AK, 所 以无法伪造请求 (PS, 尽管新的标准要求在返回 TS 和 AS 必须使用 HTTPS, 但仍有大量服务器使用 HTTP) 如果有恶意中间人,数据不会有危险 理由基本同上, 不过恶意中间人能够给客户端返回假数据,误 导客户端,但仍无法伪造出对服务端的合法请求
  21. 21. 更多的安全细节 1. 客户端需要保存好 TS 2. TS 在服务端是明码保存的, 所以如果服务端被入侵, TS 可 能会泄漏 3. 服务端用户登录页面必须是 HTTPS 4. 服务端展示客户端凭证密码的页面必须是 HTTPS 页面(很多 现有服务不满足) 5. 服务端返回临时凭证和令牌凭证时必须是 HTTPS 协议(原始 OAuth 协议为应该, RFC 改为必须) 6. 凭证的密钥应当足够长(大部分服务使用 128bit 密钥, douban 的是 64bit) 7. OAuth 不保证 API中涉及到的保密数据的安全。
  22. 22. 本地客户端的 前面介绍的是网站客户端的情况,本地客户端跟网站主要有如下 几点差异 没有回调 URL 的概念, 服务端直接在用户授权后显示对应的 verify_code, 本地客户端提供一个输入框让用户来输入 本地客户端需要一个保存CS(客户端凭证密钥)的方案,防止 被恶意用户获取到, 当然也可以不在本地保存,直接从网上 获取(注意这步保密)。 如果使用嵌入网页的方法来让用户登录, 用户无法判定浏览 器是安全的,会减弱对你的客户端的信任。
  23. 23. 目录 为什么需要 OAuth? OAuth 原理 OAuth FAQ
  24. 24. 为什么不用 HTTPS Q: 前面提到的很多手段都是为了应对窃听和恶意中间人, 全部 用 HTTPS 不就行了么? 一般情况下, 一个 IP+端口只能部署一套 HTTPS 密钥,也就 是说没法玩虚拟主机了(因为在 Host 发送前TLS连接就必须建立好 )。 SNI 扩展支持 HTTPS 虚拟主机,但客户端方面 IE6 不支持, WinXP 下 IE所有版本, Chrome, Safari 不支持. Dreamhost 之类的 Host 供应商不支持 HTTPS 虚拟主机。 HTTPS 对服务器端压力也更大 HTTPS 密钥很昂贵, 比较便宜的godaddy 每年 30 美金左 右, 贵的可达数千美金一年
  25. 25. 为什么使用 HMAC-SHA1 Q: HMAC-SHA1 需要计算两次 SHA1, 有必要么? A: 签名是为了防止窃听者和恶意中间人伪造请求, 而其他更简单的签名 方法都存在安全风险 1. 比如使用 sign = SHA1(key+data), 中间人截获了 data 和 sign, 由 于 SHA1 算法的特性,对于构造出 data' = data + padding, 可以 计算出对应的 sign' = SHA1(key+data'), 伪造成功。 2. 比如使用 sign = SHA1(data+key), 中间人截获了 data 和 sign, 如 果我们能找到 data' 满足 SHA1(data)==SHA1(data'), 那么伪造请 求 data', sign 也能通过服务端的验证 3. 对于 HMAC: sign = SHA1(f1(key)+SHA1(f2(key)+data)), 没有前 面所说的两种风险。 4. 第二步 SHA1 的参数很短(320bit), 所以对比单次 SHA1, 时间不是两 倍,而只是增加了一个很小的常数时间
  26. 26. 为什么需要 nonce 和 timestamp A: 防止重放攻击 (Replay attack) 一种重放攻击是把截获到的请求重发一次或多次, 对于 POST 这种非幂等的方法会造成服务器端的数据错误。加入 nonce 后, 首次之后的请求会被拒绝。这种攻击手法只需要窃听能 力。 另一种重放攻击是把请求拦截下来, 不发给服务器。然后等 待到合适的时间后再把请求发给服务器。也可以收集多个请 求,重新组合成合适的顺序后再发送。这种攻击手法需要中间 人能力。 由于 nonce 与 timestamp 是一起使用的,所以 timestamp 过期 后 nonce 也可以抛弃, nonce 储存容量不会无限制增长。
  27. 27. 1.0a 修复了什么Bug? A: 1.0 下存在如下的一种攻击手法
  28. 28. 1.0a 修复了什么Bug? A: 1.0 下存在如下的一种攻击手法 1. 存在两个用户: 攻击者和受害人, 存在一个客户端,这个客 户端会把用户在服务端的权限通过 OAuth 绑定到本地帐号。 2. 攻击者登录客户端, 在客户端触发 OAuth 请求, 跳转到服务 端后,不进行授权操作,保存此时的 URL。 3. 攻击者把保存好的 URL 发给受害人, 并诱导受害人完成授权 操作(注意: 此时绑定操作通常会失败, 因为因为临时凭证的 密钥部分应该只存在攻击者的 session 数据中)。 4. 攻击者访问 callback URL, 就可以绑定受害人的权限到攻击 者的帐号。
  29. 29. 1.0a 如何修复Bug? 服务器应该提醒用户, 登录链接是否来自指定的网站。 客户端应当确认,发起请求的用户和完成登录的是同一个用 户 (避免在受害者访问 callback 时就完成绑定了) 服务端会下发确认码, 攻击者无法构造出完整的 callback url, 攻击失败 申请临时凭证的协议也略有更改,用于识别 1.0a 客户端和 服务端
  30. 30. OAuth 不做什么? 只保护服务端,不保护客户端 OAuth 只保证用户在服务端的数据不被非法访问或修改, 但不保证客户端接收到正确的数据,恶意中间人可以修改 返回的数据,当然这个也可以用签名来解决。 不保护恶意浏览器/恶意操作系统攻击 用户必须自行确认自己的浏览器/操作系统是否安全。 OAuth 的安全建立在 HTTPS 之上, 攻击 HTTPS 的手段也会 影响到 OAuth 比如 DNS 污染加上伪造证书 比如 SSL 2.0 漏洞 不保护笨蛋, 用户需要教育 OAuth 授权时需要验证确实在真实的服务器上, 避免被恶意 客户端钓鱼
  31. 31. 国内现有 OAuth 服务器的问题 Douban 仍在使用 OAuth 1.0 客户端令牌展示页面没有加密 密钥只有 64bit Sohu 微博 每次认证时都要求用户输入密码, 容易造成用户麻痹, 更 容易被钓鱼网站袭击 ... PS. 仅代表当时(2010-07)的情况, 不代表现状
  32. 32. Thanks for your attention! Q&A?

×