针对近期“博全球眼球的OAuth漏洞”的分析与防范建议
据Cnet报道,新加坡南洋理工大学一位名叫Wang Jing的博士生,发现了OAuth和OpenID开源登录工具的“隐蔽重定向”漏洞(Covert Redirect)。
首先需要明确的一点是,漏洞不是出现在OAuth 这个协议本身,这个协议本身是没有问题的,之所以存在问题是因为各个厂商没有严格参照官方文档,只是实现了简版。 问题的原因在于OAuth的提供方提供OAuth授权过程中没有对回调的URL进行校验,从而导致可以被赋值为非原定的回调URL,就可以导致跳转、XSS等问题,甚至在对回调URL进行了校验的情况可以被绕过,具体将在附件中的paper中阐述。
微博安全团队4 月中旬已经率先发现该问题,并联合业务部门进行威胁的评估和落地修复方案的敲定,截止今天中午前,回调URL校验和校验绕过漏洞在开放平台已经修复上线。
来看看来自知道创宇安全研究团队Fooying与Erevus同学执笔的paper吧,针对近期“博全球眼球的OAuth漏洞”的分析与防范建议 。
鸣谢来自微博安全团队同学的帮助。
1.OAuth介绍
1.1.OAuth简介
来自OAuth的官网解释:
An open protocol to allow secure authorization in a simple and standard method from web, mobile and
desktop applications.
OAuth is a simple way to publish and interact with protected data. It's also a safer and more secure
way for people to give you access. We've kept it simple to save you time.
大概的意思是OAuth是一种开放的协议,为桌面程序或者基于BS的Web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。OAuth是一个发布并与受保护数据交互的简单方法。这也是一个更安全的访问方式。我们已经保持它的简单来节约您的时间。
简单的说,OAuth就是第三方的应用可以通过你的授权而不用知道你的帐号密码能够访问你在某网站的你自己的数据或功能。像weibo、QQ、淘宝等网站都提供了OAuth服务,提供OAuth服务的网站一般都有很多开放的API,第三方应用会调用这些API来开发他们的应用以让用户拥有更多的功能,但是,当用户在使用这些第三方应用的时候,这些第三方的应用会来访问用户的帐户内的功能和数据,所以,当第三应用要干这些事的时候,我们不能让第三方应用弹出一个对话框来问用户要他的帐号密码,不然第三方的应用就把用户的密码给获取了,所以,OAuth协议会跳转到一个页面,让用户授权给这个第三方应用以某些权限,然后,这个权限授权的记录保存在提供OAuth服务的网站上, 并向第三方应用返回一个授权token,于是第三方的应用通过这个token来操作某用户帐号的功能和数据时,就畅通无阻了。
这其实是一个授权操作的过程,用户注册帐号的网站(如微博等)提供OAuth服务,第三方服务想调用用户对应帐号的相关信息做帐号相关的操作,就会请求OAuth提供方的授权,当OAuth提供方询问用户并得到授权,就会给予第三方服务一些权限做相对应的操作。
1.2.OAuth 2.0
OAuth分为OAuth以及OAuth 2.0。OAuth Core 1.0 版本发布于2007年12月4日,由于存在可被会话定向攻击(session fixation attack)的缘故,2009年6月24日发布了OAuth Core 1.0 Revision A 版本。最终在2010年4月,OAuth成为了RFC标准: RFC 5849: The OAuth 1.0 Protocol。
OAuth 2.0的草案是在2010年5月初在IETF发布的。OAuth 2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。规范还在IETF OAuth工作组的开发中,按照Eran Hammer-Lahav的说法,OAuth于2010年末完成。
OAuth 2.0授权框架允许第三方应用程序获得指定HTTP服务的有限的访问权限。
1.3.授权交互流程
OAuth的授权有四种方式,主流采用两种方式,分别是Authorization Code(response_type=code)与Implicit(response_type=token)。
Authorization Code方式授权交互:
与Implicit方式授权交互:
2.OAuth与OpenID登录工具漏洞
2.1.漏洞发现与报道
据Cnet报道,新加坡南洋理工大学一位名叫Wang Jing的博士生,发现了OAuth和OpenID开源登录工具的“隐蔽重定向”漏洞(Covert Redirect)。
这可导致攻击者创建一个使用真实站点地址的弹出式登录窗口——而不是使用一个假的域名——以引诱上网者输入他们的个人信息。
鉴于OAuth和OpenID被广泛用于各大公司——如微软、Facebook、Google、以及LinkedIn——Wang表示他已经向这些公司已经了汇报。
Wang声称,微软已经给出了答复,调查并证实该问题出在第三方系统,而不是该公司的自有站点。
Facebook也表示,“短期内仍无法完成完成这两个问题的修复工作,只得迫使每个应用程序平台采用白名单”。
至于Google,预计该公司会追踪OpenID的问题;而LinkedIn则声称它将很快在博客中说明这一问题。
该中文版来自:http://digi.163.com/14/0503/08/9RACJBK900162OUT.html,
原英文版:http://www.cnet.com/news/serious-security-flaw-in-oauth-and-openid-discovered/
2.2. 漏洞说明
首先需要明确的一点是,漏洞不是出现在OAuth这个协议本身,这个协议本身是没有问题的,之所以存在问题是因为各个厂商没有严格参照官方文档,只是实现了简版。
问题的原因在于OAuth的提供方提供OAuth授权过程中没有对回调的URL进行校验,从而导致可以被赋值为非原定的回调URL,甚至在对回调URL进行了校验的情况可以被绕过。利用这种URL跳转或XSS漏洞,可以获取到相关授权token,危害到目标用户的账号权限。具体将在下文进行分析。
微博安全团队4月中旬已经率先发现该问题,并联合业务部门进行威胁的评估和落地修复方案的敲定,截止今天中午前,回调URL校验和校验绕过漏洞在开放平台已经修复上线。
3. 漏洞成因、利用及危害
3.1.漏洞利用
部分OAuth 2.0提供未对回调URL进行校验甚至校验可以被绕过的情况下,黑客可以通过构造钓鱼页面,用户在访问了黑客构造的页面之后,可以被获取OAuth授权中最终返回的token,通过token可以实现登陆该用户的第三方应用或者是调用OAuth提供的API进行相关操作,包括获取在OAuth提供方注册的相关资料等。
3.1.1. 回调URL未校验
如果回调URL没有进行校验,则黑客可以直接修改回调的URL为指定的任意URL,即可以实现跳转甚至是XSS。
如:
http://passport.xxxx.cn/oauth2/authorize?response_type=code&redirect_uri=http://www.baidu.com&client_id=10000&theme=coremail
3.1.2. 回调校验绕过
部分OAuth提供方在进行的回调URL校验后存在被绕过的情况。
如:
https://api.xxx.com/oauth2/authorize?redirect_uri=http%3A%2F%2Fwww.knownsec.om.www.zhihu.com%2Foauth%2Fauth%2Frequest_token%3Fnext%3D%252Foauth%252Faccount_callback&response_type=code&client_id=30638
未进行绕过修改回调URL提示校验失败
3.1.3. 利用第三方应用漏洞
这其实也属于校验不完整的而绕过的一种情况,因为OAuth提供方只对回调URL的根域等进行了校验,当回调的URL根域确实是原正常回调URL的根域,但实际是该域下的一个存在URL跳转漏洞的URL,就可以构造跳转到钓鱼页面,就可以绕过回调URL的校验了。
如:
https://api.xxx.com/oauth2/authorize?client_id=204649&response_type=token&redirect_uri=http%3A%2f%2fpassport.xxxx.com%2fuser%2fcrossdomain%3Fact%3Dlogout%26return_url%3Dhttp%3A%2f%2fwww.knownsec.com
3.1.4. 授权验证参数的不正确使用
部分第三方应用在授权过程中采用如state里包含access token接收的回调URL,但是因为OAuth提供方只对回调URL,即参数redirect_uri的值进行校验,就可以导致黑客可以随意构造回调的URL,就导致问题的出现。
3.1.5. 绕过方式
1) redirect_uri=http%3A%2F%2Fwww.a.com?www.b.com
2) redirect_uri=http%3A%2F%2Fwww.a.com.www.b.com
3) redirect_uri=http%3A%2F%2Fwww.a.com:@www.b.com
其中www.a.com为钓鱼或者接收token的页面,www.b.com为实际回调的URL
3.2. 漏洞危害
3.2.1. URL跳转
黑客可以利用该问题构造相关的钓鱼页面,诱使用户访问从而造成用户的帐号被窃取等相关损失等。
3.2.2. API调用
因为黑客可以通过给问题获取到用户的相关授权token,可以通过token调用OAuth提供方的相关API方法进行相关的操作,包括获取用户资料、发表微博等等(如腾讯API调用可以参考http://wiki.open.qq.com/wiki/API%E5%88%97%E8%A1%A8)
3.2.3. CSRF
利用CSRF技巧进行隐蔽攻击,可以获取到用户的token,然后使用token调用相应开放平台的API接口,登陆第三方应用并对用户的账户进行相关操作。
这意味着黑客可以通过该问题构造对用户进行钓鱼甚至是获取用户的注册资料、登陆用户帐号进行相关操作等
4. 漏洞影响
通过对国内部分提供OAuth 2.0的网站进行测试和调查,发现均不同程度的存在以上的问题。
从测试结果可以看出,除了百度绕过未进行测试外,其他都存在问题,而且好几个甚至对回调URL都没有进行校验,而对回调URL进行校验了的又可以被绕过。
5. 漏洞防范
5.1. OAuth提供方
1) 对redirect_uri进行全路径验证,避免URL跳转情况
2) 参数state即用即毁
3) 首次授权,强制验证
4) 获取access_token,验证App secret
5) 回调URL进行跳转校验等
6) 加强redirect_uri验证,避免绕过
5.2. 普通用户
对于普通用户来说,其实没有什么好恐慌的,这次问题的利用的前提是对构造URL的访问,所以主要是针对URL提高警惕和识别,需要注意以下几点:
1) 只授权给可信的第三方应用
2) 不要访问不明来路的链接,正常的应用授权应该是通过页面中的登陆按钮等方式进行的。
PDF版下载地址:
http://blog.knownsec.com/wp-content/uploads/2014/05/%E9%92%88%E5%AF%B9%E8%BF%91%E6%9C%9F%E2%80%9C%E5%8D%9A%E5%85%A8%E7%90%83%E7%9C%BC%E7%90%83OAuth%E6%BC%8F%E6%B4%9E%E2%80%9D%E7%9A%84%E5%88%86%E6%9E%90%E4%B8%8E%E9%98%B2%E8%8C%83%E5%BB%BA%E8%AE%AE.pdf
附录
http://www.cnet.com/news/serious-security-flaw-in-oauth-and-openid-discovered/
http://homakov.blogspot.com/2014/05/covert-redirect-faq.html
http://dannythorpe.com/2014/05/02/tech-analysis-of-serious-security-flaw-in-oauth-openid-discovered/
- Topshelf 支持Mono 扩展Topshelf.Linux
- 如何在 React Native 实现类微信小程序平台:WebView 调用原生组件
- 如何运营一个开源项目并取得较大影响力?
- ASP.NET Identity 2新增双重认证、帐号锁定、防伪印章功能并修复了一些bug
- Serverless 应用开发指南:基于 Serverless 与 Lambda 的微信公共平台
- Serverless 应用开发指南:serverless 的 hello, world
- 通过一组RESTful API暴露CQRS系统功能
- 通过使用结构化数据 JSON-LD,我为网站带来了更多的流量
- 使用 OWIN Self-Host ASP.NET Web API 2
- c#开源消息队列中间件EQueue 教程
- Serverless 框架 OpenWhisk 开发指南:使用 Node.js 编写 hello, world
- GOTO Berlin: Web API设计原则
- 使用 ServiceStack 构建跨平台 Web 服务
- 使用 OpenWhisk 自建 Serverless 服务
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面试官:spring的BeanFatory和FactoryBean区别
- Saltstack_使用指南06_远程执行-指定目标
- 什么是缓存击穿、雪崩、穿透
- 如何卸载CDH7.1.1
- java8 stream的这些开发技巧,你值得好好收藏
- 面试官:mybatis中#{ }和${ }的区别
- python 学习笔记(9)——Python 正则表达式
- 万能的BeanPostProcessor是如何让spring无限扩展的?
- spring解决循环依赖为什么要用三级缓存?
- 深入剖析ThreadLocal
- spring事务的这10种坑,你稍不注意可能就会踩中!!!
- 面试前看了这篇spring事务的文章,让我多要了2k的工资
- 面试时被问到单例模式,怎么回答才能让面试官眼前一亮?
- 老司机手把手教你编写自己的springboot starter
- 实战|如何消除又臭又长的if...else判断更优雅的编程?