oauth: how and why?

32
OAuth: How and Why? LI Daobing (盛大创新院) [email protected] @lidaobing July 2010

Upload: li-daobing

Post on 24-May-2015

4.745 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: OAuth: How And Why?

OAuth: How and Why?

LI Daobing (盛大创新院) [email protected]

@lidaobingJuly 2010

Page 2: OAuth: How And Why?

目录

为什么需要 OAuth?

OAuth 原理

OAuth FAQ

Page 3: OAuth: How And Why?

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

要不要先改密码,再来输入?还是干脆直接放弃?

新浪还可相信,小网站呢?

Page 4: OAuth: How And Why?

Facebook 做法

1. 我确实是从 Facebook 点击过来的2. 确实是 Google 的网站3. 申请的权限仅限我的联系人

Page 5: OAuth: How And Why?

查看权限, 回收权限在整个过程中: 1. 密码没有泄漏给 facebook2. 同时可以随时回收权限

Page 6: OAuth: How And Why?

更多情形

一个 twitter 客户端

一个手机上的 rememberthemilk 客户端

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

一个 Blog 客户端

...

Page 7: OAuth: How And Why?

需求再整理

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

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

Page 8: OAuth: How And Why?

OAuth 能满足你的需求!

Page 9: OAuth: How And Why?

目录

为什么需要 OAuth?

OAuth 原理

OAuth FAQ

Page 10: OAuth: How And Why?

标准历史

2007-10: OAuth 1.02009-06: OAuth 1.0a

主要解决一个安全漏洞 (后面有详细介绍)

2010-04: RFC 5849名词变更, consumer->client, ...时间戳不要求递增小修改

Page 11: OAuth: How And Why?

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

Page 12: OAuth: How And Why?

请求流程

Page 13: OAuth: How And Why?

详细数据流 (1/5)

缩写CK: 客户端凭证keyCS: 客户端凭证secretTK, TS: 临时凭证 key 和 secretAK, AS: 令牌凭证 key 和 secret (A 代表 access token)

Page 14: OAuth: How And Why?

详细数据流 (2/5)

0. 初始状态, 客户端持有 CK 和 CS1. 用户发起授权操作: 用户点击位于客户端上的一个按钮, 发起授权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

Page 15: OAuth: How And Why?

详细数据流 (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。

Page 16: OAuth: How And Why?

详细数据流 (4/5)

7. 用户访问回调URL, 该URL 中包含 TK 和 verify_code8. 客户端申请令牌凭证 客户端通过 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

Page 17: OAuth: How And Why?

详细数据流 (5/5)

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

11. 服务端返回 API 结果根据 AK 从数据库中调出 [AS, CK, user_id, rights], 校验 CK 及签名, 检验访问的 API 是否在授权范围内, 使用 user_id 对应的数据支持 API, 返回结果到客户端

Page 18: OAuth: How And Why?

请求流程 (补上每步发送的数据)

Page 19: OAuth: How And Why?

签名范例

GET /photos?file=vacation.jpg&size=original HTTP/1.1 #请求 PathHost: photos.example.net #请求 HostAuthorization: OAuth realm="Photos",oauth_consumer_key="dpf43f3p2l4k3l03", #CKoauth_token="nnch734d00sl2jdk", #TK/AKoauth_signature_method="HMAC-SHA1", #签名方法oauth_timestamp="137131202", #时间戳oauth_nonce="chapoH", #nonceoauth_signature="MdpQcU8iPSUjWoN%2FUDMsK2sui9I%3D" #签名

1. 从客户端发送到服务端的每个请求都需要签名2. 除了前面讲到的数据外, 需要额外加上 oauth_timestamp(时间戳) 以及 oauth_nonce, 用于防止重放攻 击 (后面有详解)3. oauth_signature_method 用于指定签名方法, oauth_signature 为签名签名细节参见 RFC 5849 3.4 节 , 简单来说就是把请求的内容拼接为字符串(包括 GET/POST), 然后使用 对应的密钥签名

Page 20: OAuth: How And Why?

需求回顾

我想授权B访问我的数据,同时不暴露我的用户名和密码用户名和密码都是在 A 服务器上输入的, 从未暴露这种授权可以随时回收在 A 服务器上随时可以回收如果信息被窃听,数据不会有危险API 请求需要用 CK+AK 来签名, 数据窃听只能听到 AK, 所以无法伪造请求 (PS, 尽管新的标准要求在返回 TS 和 AS 必须使用 HTTPS, 但仍有大量服务器使用 HTTP)

如果有恶意中间人,数据不会有危险理由基本同上, 不过恶意中间人能够给客户端返回假数据,误导客户端,但仍无法伪造出对服务端的合法请求

Page 21: OAuth: How And Why?

更多的安全细节

1. 客户端需要保存好 TS2. TS 在服务端是明码保存的, 所以如果服务端被入侵, TS 可

能会泄漏3. 服务端用户登录页面必须是 HTTPS4. 服务端展示客户端凭证密码的页面必须是 HTTPS 页面(很多

现有服务不满足)5. 服务端返回临时凭证和令牌凭证时必须是 HTTPS 协议(原始

OAuth 协议为应该, RFC 改为必须)6. 凭证的密钥应当足够长(大部分服务使用 128bit 密钥,

douban 的是 64bit)7. OAuth 不保证 API中涉及到的保密数据的安全。

Page 22: OAuth: How And Why?

本地客户端的

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

没有回调 URL 的概念, 服务端直接在用户授权后显示对应的 verify_code, 本地客户端提供一个输入框让用户来输入本地客户端需要一个保存CS(客户端凭证密钥)的方案,防止被恶意用户获取到, 当然也可以不在本地保存,直接从网上获取(注意这步保密)。如果使用嵌入网页的方法来让用户登录, 用户无法判定浏览器是安全的,会减弱对你的客户端的信任。

Page 23: OAuth: How And Why?

目录

为什么需要 OAuth?

OAuth 原理

OAuth FAQ

Page 24: OAuth: How And Why?

为什么不用 HTTPS

Q: 前面提到的很多手段都是为了应对窃听和恶意中间人, 全部用 HTTPS 不就行了么?

一般情况下, 一个 IP+端口只能部署一套 HTTPS 密钥,也就是说没法玩虚拟主机了(因为在 Host 发送前TLS连接就必须建立好 )。SNI 扩展支持 HTTPS 虚拟主机,但客户端方面 IE6 不支持, WinXP 下 IE所有版本, Chrome, Safari 不支持.Dreamhost 之类的 Host 供应商不支持 HTTPS 虚拟主机。HTTPS 对服务器端压力也更大HTTPS 密钥很昂贵, 比较便宜的godaddy 每年 30 美金左右, 贵的可达数千美金一年

Page 25: OAuth: How And Why?

为什么使用 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, 时间不是两倍,而只是增加了一个很小的常数时间

Page 26: OAuth: How And Why?

为什么需要 nonce 和 timestamp

A: 防止重放攻击 (Replay attack)一种重放攻击是把截获到的请求重发一次或多次, 对于 POST 这种非幂等的方法会造成服务器端的数据错误。加入 nonce 后, 首次之后的请求会被拒绝。这种攻击手法只需要窃听能力。另一种重放攻击是把请求拦截下来, 不发给服务器。然后等待到合适的时间后再把请求发给服务器。也可以收集多个请求,重新组合成合适的顺序后再发送。这种攻击手法需要中间人能力。由于 nonce 与 timestamp 是一起使用的,所以 timestamp 过期后 nonce 也可以抛弃, nonce 储存容量不会无限制增长。

Page 27: OAuth: How And Why?

1.0a 修复了什么Bug?

A: 1.0 下存在如下的一种攻击手法

Page 28: OAuth: How And Why?

1.0a 修复了什么Bug?

A: 1.0 下存在如下的一种攻击手法1. 存在两个用户: 攻击者和受害人, 存在一个客户端,这个客

户端会把用户在服务端的权限通过 OAuth 绑定到本地帐号。2. 攻击者登录客户端, 在客户端触发 OAuth 请求, 跳转到服务

端后,不进行授权操作,保存此时的 URL。3. 攻击者把保存好的 URL 发给受害人, 并诱导受害人完成授权

操作(注意: 此时绑定操作通常会失败, 因为因为临时凭证的密钥部分应该只存在攻击者的 session 数据中)。

4. 攻击者访问 callback URL, 就可以绑定受害人的权限到攻击者的帐号。

Page 29: OAuth: How And Why?

1.0a 如何修复Bug?

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

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

服务端会下发确认码, 攻击者无法构造出完整的 callback url, 攻击失败

申请临时凭证的协议也略有更改,用于识别 1.0a 客户端和服务端

Page 30: OAuth: How And Why?

OAuth 不做什么?

只保护服务端,不保护客户端OAuth 只保证用户在服务端的数据不被非法访问或修改, 但不保证客户端接收到正确的数据,恶意中间人可以修改返回的数据,当然这个也可以用签名来解决。

不保护恶意浏览器/恶意操作系统攻击用户必须自行确认自己的浏览器/操作系统是否安全。OAuth 的安全建立在 HTTPS 之上, 攻击 HTTPS 的手段也会影响到 OAuth

比如 DNS 污染加上伪造证书比如 SSL 2.0 漏洞

不保护笨蛋, 用户需要教育OAuth 授权时需要验证确实在真实的服务器上, 避免被恶意客户端钓鱼

Page 31: OAuth: How And Why?

国内现有 OAuth 服务器的问题

Douban仍在使用 OAuth 1.0客户端令牌展示页面没有加密密钥只有 64bit

Sohu 微博每次认证时都要求用户输入密码, 容易造成用户麻痹, 更容易被钓鱼网站袭击

...PS. 仅代表当时(2010-07)的情况, 不代表现状

Page 32: OAuth: How And Why?

Thanks for your attention!

Q&A?