奇虎360技术总监任寰:Chrome安全架构的进化

2012-12-14 09:38 | 次阅读 | 来源:CSDN 【已有0条评论】发表评论

关键词:SyScan | 作者:朱慧涛 | 收藏这篇资讯

12月13-14日,SyScan首次登陆北京,携手奇虎360合力举办SyScan360国际前瞻信息安全会议。此次活动为期两天,将涵盖Windows、Android、iOS、浏览器、软件漏洞挖掘攻击等各个方向互联网安全话题,为国内外从事互联网安全领域的研究同行们提供良好的交流与合作的平台。同时本次大会还将汇集国际安全领域最新的研究成果,共享最新的安全技术,众多国际重量级的演讲嘉宾将汇聚一堂,分享最前端的信息安全的理念。

奇虎360技术总监任寰长期从事Chrome浏览器的设计和开发,曾是Chrome浏览器Windows版和Android版多个模块的开发负责人。他为大家介绍了Chrome这些安全机制的设计思想,基本原理,及发展演变,并对其有效性进行了评估。 

奇虎360技术总监 任寰

他认为Chrome多进程的架构要求Chrome具有很强的兼容性,渲染进程和扩展进程都需要进行隔离。沙箱即降权,是一种较好的浏览器防护方案。最后任寰总结道,设计思想实际上有四点,第一个就是降权,按最小权限执行,同时实行隔离,在做的其中,实践上注意两点,就是利用系统内置安全性比较好,另外在安全性和可用性或者是性能上达到一个平衡。

以下是演讲实录:

如何尽可能地降低漏洞危害

任寰:大家好,很高兴今天下这么大雪还和这么多人一起分享。实际上我是发现今天车不好开了。我自我介绍一下,我现在在360负责360浏览器的开发,来360之前在Google工作了五年,一直负责Chrome浏览器的开发,负责过很多个模块。之前演讲者讲的很多是攻击,就是怎样来攻破一款软件。那么我今天实际上是从产品开发角度讲,也就是讲防守,就说你要做一款软件,你怎么让你的产品更安全,相当于从另外一个角度讲这个工作。大家都知道,你写软件只要是人、只要是工程师都会犯错误,都可能有漏洞,这是不可避免的。所以通常第一步大家都知道,就是要尽量减少漏洞,这里头我们有各种各样的方法,比如说用静态分析、用FUZZ,还有Google讲的各种各样的寻找漏洞计划,目的都是要减少漏洞,你肯定会用到第三方的库,这里面也会有漏洞,所以漏洞是不可避免的,在这种情况下你怎么设定软件安全架构,将危害降到最低。所以通用的方法就是一条,尽量的Attack surface,你需要的权限刚刚够你完成任务就可以了。

有一些任务你一定需要高权限,那么你会做一些隔离,所以隔离和降权是两个方面,基本上是所有的安全架构思路都是这样来的。这里重点解决什么问题呢?其实是一个兼容性问题,你降权容易,但是程序的降权工作是最大工作量,而不是安全机制本身。这里头最主要一条就是我们从经验出发发现,降权架构要一开始就设定,一开始设定软件写起来比较容易,如果你中间现改,会花无数多的代价把这个真正改好,你把程序和API都用上,你开始限的比较死,最后的产品也会比较符合安全架构。

先给大家看Chrome这个架构,Chrome是有好多个进程组成的,之所以有这么多进程,因为安全考虑是基本原因。进程是浏览器处理网络的一种进程,它有最高权限和你应用程序所带的权限是一样的。还有一个进程是渲染进程,这个渲染进程就是说我们说的渲染内核部分,大家都知道浏览器有各种各样内核,比如说IE用的Chrome,或者国外很多浏览器用WEB KIT,渲染主要作用是给你网页内容,你渲染成一个位图。还有一个就是扩展,我估计在座很多都是Chrome的用户,大家都在Chrome装过扩展,比如说过滤这种我指扩展就是这个。还有像插件,像Flash这样,除此之外还有GPU进程,就是负责硬件加速,为什么有这么多进程,实际上带来很多复杂度,但是目的基本上主要一条这里头有稳定性的原因,主要一条就是为了安全考虑,就是把需要不同权限的任务放到不同进程里头,给它不同的权限限制,这就是沙盒机制,沙箱机制就是主进程设定,今天我们从这个架构出发,对每一个进程限制进行分析,讲一讲它的设计思想。

Chrome到今天也不是一开始就这么设计的,它实际上是一个逐渐演进的过程。最早的Chrome版本是多架构,是没有沙箱的,当时从2006年中期开始开发的,在2007年的时候,当时出现了一个影响比较大的IE一个漏洞,具体想不起来了,但是涉及到Gift,因为它没有影响到VIST ,因为vist有一个Low integrity mode,我们从2007年开始做渲染级沙箱,因为渲染级沙箱是后做,所以把渲染的程序重写,你这个降权机制一开始就要有,否则后面的工作量非常大。2008年Chrome正式发布,2008年发布之后,做最大的改动就是加了扩展,像Firefox一样,所以今天我对扩展做一个重点讨论,另外分析一下它的效果。

之后就是硬件加速成为热门,如果大家熟悉HTML5的话,像硬件加速必须通过GPU加速,这个时候也是因为沙箱的考虑做了一个进程外的GPU。还有一个同时在做的就是插件,现在看来最弱一款是插件,因为插件本身有很多兼容性的软件,所以在这方面一直在做一个新的叫PPAPI的插件架构,另外也对最通用的架构FLASH和PDF Reader做了一个改造,总的是这么一个演进情况。

今天我按这个顺序总体讲一下。第一个我们就来介绍渲染这个沙箱,渲染沙箱是属于我们叫主沙箱,因为是防护性最强的沙箱。刚才我讲了渲染进程作用是什么?渲染进程的作用就是说用渲染内核或者渲染引擎给你的网页内容渲染出来,要么是位图,要么是直接显示在系统窗口和设计窗口上。渲染沙箱设计原理是这样考虑,当时设计思想就是一定要在所有的系统上都能用,所以尽量利用系统已有的机制,这个设计思想和IE不一样,IE在VIST又加了一个Low integrity mode,它是本身带了一些系统检查,当时是一定要用系统机制基础上降权。第一先降,第二让它真正跑起来。

当时有哪些机制呢?我把系统能用到的安全机制都拿出来,基本上沙箱就这么来的,系统有哪些机制,最主要是每个进程,大家知道有一个Access token,当你访问系统资源,比如说文件、注册标箱等等,系统会拿你Access token,叫资源上允许访问的Access token,不符合的话就不能进去。我们把这个Token放在一个NO Token。另外就是Createrestricted,只要是Token检验了,都不能访问。

第二个就是Job,Job就是提供一些额外的限制,就是把这个渲染进程家到Job里面,我这里定了两个,一个是可以放ACTIVE process,这个是不能进程再创进程。还有一个是Red clipborad不能有剪贴板。第三还有一个是Desktop,Windows有一个设计缺陷,就是同一个Desktop可以发消息,从后期来看是设计上的一个缺陷。第四个是GDI。比如说最早的FAT文件系统没有Token检验。我们的方法是这样,就是让你什么权限都没有,在看你需要什么权限一项一项给你加,就是属于白名单的机制,这个是我们自己写应用程序可以改,很多原来沙箱产品是没法改的,别人应用程序他只或用类似于限制危险操作的方式来做。我们就是可以改自己的东西。

我刚才提到的,这个沙箱的设计原理其实很简单,正因为它简单,所以最后看效果非常强,想突破这个关很难,不是一般的沙箱程序,因为它是在执行控制危险操作,但是有兼容性问题,有两个问题,一个就是说你这个程序在刚启动的时候一定要有权限,有两个原因,一个是操作系统本身Loader会在程序本身的Context做很多事,帮你设计很多环境,上来把权限降最低根本跑不起来。还有CRT,每个程序都会用,它也需要初始化,初始化的时候也需要很多权限,控制不住,所以这个设计是这样的,实际上分成两步,第一步程序刚刚跑起来的时候,它其实没有沙箱的,所有高权限执行,当进入你自己内函数的时候,程序自己的内函数的时候,允许做一些必要的初始化,但是在你跟外界联系之前,我们设计一个不可逆的,就是我刚才说的限制机制都起作用,这是不可逆的过程。

这样的话,就有一个问题了,在你调Lower token之前,要把Handle关掉,不关掉会有问题,另外做一些校验,你该管的Lower token就要关了。

第二个是我们自己渲染进程,毕竟要做一些操作,做什么操作呢?包括网络操作,总要从网络上取数据的,包括读写缓存,读写Cookie,你加那么强的沙箱做不了怎么办?所以我们处理就是说这些东西全在统计层做,就是说凡是涉及到网络操作、文件操作的,Cookie都去做。这里也有一个好处,原因就是如果我们把不同的标签放在不同进程里面,有的是Cookie要共享,如果在进程里面这个Cookie进行不了,所以我们都进行Cookie,包括网络缓存也是一样,能够统一利用。

这里有一个原则,它至少有些事能办,至少能跟主机通信,要通信进行一些主进程的操作,我们对有些API进行Hook,判断它有没有这个权限,把这个请求移到主进程,主进程确认他确实需要办这件事,帮他读取这个资源再传回来,就是这个机制。我这里画了一个IPC,Render就是一个渲染进程,它有一个策略决定你能不能这么做。

这个Inteception在座可能比较熟悉,就是主进程在创建渲染进程的时候,是用Suspended的方式创建进来的,他用一种方式重定一些NTDLL函数,同时把这个策略放进去,所以开始这些跟NtMapviewOfSection以后,如果在动态库需要进行Exe dll函数就换掉了。这里可以再提醒一下就是说,这里头的不是沙箱,而是为了保证兼容性。

我们用了沙箱,沙箱防护级别很强,主要工作量是你有这个沙箱,你的程序跑不跑得起来,刚才我介绍了就是说很多比如说网络操作、文件操作都要拿到主进程里去做,还有一个工作就是你渲染的时候如果给他一个Windows,他就会WindowsPaint,但是这里他做不了,我们就是用主进程进行Paint,他把位图传到主进程,这个主进程代替渲染进程配制到Screen,这里会有一些额外的复杂度,尤其是性能方面的影响。比如说我要你马上Paint,特别容易卡,会觉得反应慢。所以说后来做了一个机制就是缓存机制,其实解决性能问题就是两块。当需要更新的时候,就拿缓存去更新,渲染更新就是异步更新位图,这就解决了比较主要的问题。

大家知道Windows的窗口非常复杂,而且子窗口很容易卡到主窗口,这个网页渲染的时候会很慢,对窗口响应,往往让浏览器整个界面不动,通过这个其实也顺带解决这样的问题,因为没有窗口了。这里还有一个问题就是插件,就是当我们用了沙箱以后,最大难点地方是在插件上,大家知道Flash在渲染内核领域,他自己本身调用无数系统API,他在那种情况下根本执行不了,所以后来我们就做了折中,让这个Flash本身或者插件都在进程外执行。这个进程外执行和原来的Flash本身不一样,它和渲染进程内核之间有很多同步消息交互,你把这个弄到进程外之后,这个消息会同步消息发脱,会嵌套消息,传过去传过来,很快出问题。所以当时为了把这个问题改好,就是让Flash在进程外执行,前前后后花了一年,到后期我们还在解决这个问题,到最新的PPAPI,所以我前面说了如果一开始不做后面工作量会很大。

我刚才介绍了渲染进程有沙箱,渲染进程和主进程要隔离,其实渲染进程之间也是要隔离的,就是网页之间不能互相影响。所以我们有一个Process Model,比如说每一个渲染就是一个模式,还有一个每一个Site为,比如说Google.Com,比如说Gmail Calendar Google docs,我不打开一个Gmail,里面有一个Google docs。现在系统浏览器默认的就是第三种方式,就是Process per instance。

这种进程隔离不是一种强防护,因为尽量做,因为你进程是上限,不可能无限制开下去,一般到二十个就开始复用了,算是Defense Indepth隔离。有一些渲染进程是一定要隔离的,到此我大概讲了渲染进程的方式,就是防护机制。

从效果看,Chrome渲染进程沙箱是比较成功的设置,它有很多原因,一个是防护设置非常强,另外又非常轻量,不是自己创的,是利用系统的机制。而且利用系统机制尽可能达到Security boundary,我们沙箱就是把你所有想到的降到最低就是这个思路,它非常轻量级别,而且非常有效。所以说渲染级的沙箱设计,从实际效果看是一个比较成功的设计。

下面我们就是说在渲染基础上我们讲一讲扩展,就是扩展的安全设计,扩展是从2008年开始做,做扩展的时候,就吸取渲染这个教训,花大量工作解决问题,一开始就想好。扩展用哪些转,一般来说有三类,一种是Content script,就是在页面实行脚本,常见的Adblock就是这种。还有一种是扩展本身执行的脚本,通常写一个Backgoudn page,比如说你用的扩展是邮件提醒,或者是很多人如果在12305买票的时候,有一个信息问你拿没拿到票。还有一个扩展就是有系统和应用级的权限,这个扩展完成一些比较更高级别的工作。比如说有的扩展帮你静音,肯定要带npapi,扩展有很多种,在这种情况下怎么设计。返回我们原来的思路就是降权。所以Content script在渲染进程直接进行,同时我们有一个JS sandbox可以让它跟页面隔离开。平时的扩展脚本就是在单独的脚本里面进行。扩展本身和浏览器有一些交互,最后扩展需要最上面我写的Plugin,基本是在插件里执行,基本就这么几个元素。

所以这里用到互相防护可以说有三层,第一层防护就是在页面里执行的Content script,这个是第一层的防护,这个是最危险的,加入这个被攻破了,还有第二层,这里我们也做了一个防护。第三级就是校验它的权限,最后就是发布验证机制。所以扩展系统的安全设计就是围绕四个方面,前三个防护一个校验来进行设计的。这里面从理论上来讲,我们降权等级非常多,但是带来的复杂度也高,但是是一个均衡,就是你设计差不多,比较合理的级别和防护。

第一级防护我们叫JS的沙箱,如果熟悉浏览器就清楚了,引擎渲染,一个渲染部分,还有Js engine,还有一个叫Binding,把这两个能够对应起来。js脚本执行的时候,在他的环境中执行,然后当需要操作Dom对象的时候,就可以操作。页面脚本的变量看不到扩展脚本的变量,他们可以同时操作一个Dom数是可以的,但是它的jsengine是独立的,互相看不到,同样扩展和扩展之间都看不到,工程师带有不同的库,你带有不同的库存没关系,因为可以加载,这个好处就是在页面上执行多个扩展,而且没有互相影响兼容性问题,因为我们知道Js全是全局的。它的好处就是如果这个页面脚本上有恶意代码,不容易影响扩展脚本。这是第一层。

第二层防护就是我们说的,页面脚本和扩展脚本之间的防护,Content—script是一个渲染脚本,这个扩展本身就是在进程里头,它的权限比普通的渲染进程要高。第一个它可以发xml http请求,这个在一般的页面做不到。这个渲染是放给扩展进程,正常的渲染进程没有给这些权限。但是这个沙箱的机制,这个沙箱机制本身我们说的一模一样,因为我们刚才提到几个权限,加载Plugin,但是进程本身防护和渲染防护是一样的,都是同样的。

我们有了隔离,他们两个是要互相通信的,所以在Chrome里面也设计了页面脚本和扩展之间互相通信,我这儿简单列了一下几个常见的,比如说第一个就是从页面给扩展发一个消息,第二个是扩展给页面发一个消息,后面是创建连接。还有如果说第三个是怎么接收一个消息。这个意思就是说我们隔离支付就是提供某种消息机制,让他们互相访问。

第三层隔离就是你从扩展层你怎么限制它的权限,让它怎么做就怎么做的事。这个其实各个系统设计思路差不多,比如说类似于Android的APP一样,扩展有一个Manifest,这个列出了扩展运行的时候需要的权限,比如说他要跟页面交互,他要访问你的收藏夹,另外他要对Google.com做请求,另外他需要无限制本地存储,这就是权限。然后浏览器会做一定的校验。

还有一个你用Chrome创建扩展的时候,他会自动给你形成Private Key和publicKey,当你以后更新的时候,他就知道是同一个作者写的更新。我们现在很多,机遇双核浏览器七八个,每个都有应用商店类似的机制。这里头当你更新的时候,如果有新的权限要提示一下用户,确保在用户感知的情况下能装。这里头主要是权限控制,再一个就是发布机制。

我们讲了到底有没有效,我们需要拿真正的攻击来评估一下,常见对扩展的攻击出现漏洞有两类,一类叫网络攻击,就是你这个是Script source http,因为扩展在Https网页注脚,如果扩展不注意会给Https带来风险。

还有一个攻击叫跨越。这个有很多的都是做的跨越的,有一个作者在刚刚结束的UC Berkeley的作者,他拿了100个扩展,随便挑的,在一百个扩展里头,有四个扩展有问题,七个漏洞,这个漏洞我指可能被利用的漏洞,还不是代码中出的Bug,是突破了防护,能够对用户产生威胁。这里头我大概列一下他们提供的数据,就是上面一个表列出了在哪儿发现的漏洞,这个Core extension是指本身的脚本,还有页面脚本,还有因为这个扩展有漏洞给这个网站带来风险,所以叫WEBSITE,这个WEB Attack就是攻击。下面这个表统计了一下漏洞个数,可以看到就是说左边上面第二栏是头五十个最热门,第三栏就是随便挑五十个。一个有趣的现象,发现最热门五十和随便挑五十个都差不多。谁都会犯错误,按理说头五十个最热门应该是更专业一些扩展的程序员写的,但是也有可能头五十个最热门代码复杂度高一些。但是就是说总的这个情况是安全机制没起什么作用,一方面有漏洞,第二个没有防住。

我们看什么问题呢?一个就是从这个数据看,其实这个jsSABox还是可以的,因为它可以阻止Html导致的问题。一个证据就是实际上你最后看出来这个漏洞,我们假定这个程序员写代码的时候注意力都差不多,按理说是差不多比例。但是为什么在Core extension少,分析被防住的,实际上是BUG,但是没有漏洞,就是Core extension确实隔离了两个JS环境,但是Process separation,就是把扩展进程和渲染进程隔离开,就是没有防护的漏洞。常见的扩展漏洞都是Cross script这种,等于说我们用炮打一个蚊子,或者说我有很强的装甲,但是现在防传染病,防食物中毒,这个隔离是尽管很强,但是没有真正去防治该有效的攻击。

真正问题在什么地方呢?如果我们单看Cross,就是XSS的问题,说到底就是数据和脚本不分,页面操作数据和脚本混在一起,拿到数据就执行,不知道什么是数据,什么是脚本,所以在这方面隔离上下工夫,而不是说还套用老的渲染进程沙箱,这是一个问题。所以改了,改了就是重点看Content scriptpolicy,主要就是解决XSS一些问题,就是数据和代码不分的问题,在扩展V2里面,第一是用CSP,就是用Script source self。第二就是彻底禁掉了EVAL。还有就是Object src self,就是像Flash第三分插件,有了轻量级的东西,发现前面发现51个有关的机制就移到这上面去了。

刚才分析了扩展系统的一个方面,我们再更全面看一下扩展设计。

一个扩展攻击的模式,其实有很多个,一个就是我们刚才讲了,就是恶意网页攻击扩展,我们所说了那么多降权执行,还有分离什么这是主要设计的目标。但是还有一个问题,当时设计扩展的时候没有多考虑,但是现在看来是一个突出问题,就是恶意扩展,你执行起来是有无疑的,这个防护是比较弱的,因为浏览器信任你。现在浏览器同步扩展,实际上就是说使这个问题更严峻一些。

还有一个问题就是说没有考虑到扩展对网页的攻击问题,这个还是没有好好思考的一个方面。目前来说最形势严峻的,就是恶意扩展。因为扩展从某种意义上来讲,如果浏览器越来越像一个平台、操作系统,扩展就像一个应用程序就是APP,我们知道恶意扩展是有的,但是没有像Android那么流行的地步,所以没有引起黑客主要注意。但是它是一个非常潜在的一个方向,所以设计上这一块有在做一些思考。

第一步首先我从空中21开始,只能从WEBSTORE进行扩展,因为这个Chrome本身也是最终和Android一样,有一个Webstore,但是有一批双核版,都是自己的应用商店,就跟Android系统可能在我们这儿有无数第三方应用商店一样。这里如果你去看Android系统,最大的攻击来自叫Repackage,就是85%以上的恶意软件,就是把已有的软件重新开一下,又骗用户下载,带回去病毒。这里面当然Google在Android上出了一种什么新的APP verification,但是这个需要积累数据,还不是很明显,这是扩展下的主要考虑方向,就是把扩展和App store设计好。

总的来看,扩展设计也是一个不断演进的过程,而且随着当初第一版设计过多的借鉴了渲染沙箱的设计,没有在一些真正该多下工夫的地方,或者说重视不够,这本身也是一个引进的过程。

下面讲一下GPU,GPU怎么做呢?

因为我会最后讲的稍微快一些,大概从2009年开始,浏览器硬件加速是一个热点,这里头成了热点以后,各个浏览器应用系统提供的Directx,或者是D加速手段来加速渲染效果,这个对于Chrome提出一个挑战,因为如果你GPU,如果属性计算机图形学的知道,有一个GL context,这个是不能跨进程的,所以你要加速只能在渲染上,至少现在办不了。最大挑战就是你是不是要做妥协,结论就是不妥协,还是要把沙箱坚持到底。GPU如果这样的话,GPU只能在进程外干,实际上最后架构是这样的,我们又开了一个GPU process,GPU进程专门干这个事,GPU进程是一个窗口,因为它需要汇总变成一个窗口,渲染进程我们实际上对GPU所有系统,GPU封装、包装,他把数据和GPU的命令,全部发到GPU进程,在那儿进行操作,所以中间IPC量非常大,所以这个方面也就是说导致很长时间GPU稳定性和效率上出问题,就是因为渲染和GPU之间数据传输量太大。还有就是系统稳定性,你可以想象,如果我们开了Flash,Flash四个进程同时进行协调,这个复杂度高了至少两个数量级。

总结一下就是说这个GPU沙箱很简单,就是沙箱里头,刚才我们讲了其实最重要是Token,Token我们加了三个C,就跟Everyone一样,然后连到Interactive desktop,难点不是在这种情况下,而是在这种情况下还能工作,还不能失去性能。因为各个浏览器对评测非常重视,出一个评测大家都要测一下,所以这里实际上对于Chrome的评价架构压力非常大,在这种架构里面跑的不比别人慢。

最后讲讲插件,插件一开始就有很多问题。

因为我们刚才讲了插件本身因为一些问题没有沙箱的,在进程外执行了。某种意义上来讲,插件是最弱一环。早期在这方面做了一些预防性的工作,比如说它有一个黑名单,如果有插件就加载,不是自动播放Flash,至少给用户一个机会,不会被立刻攻破。还有从很早开始就自带Flash player,还有就是给Integrity mode加沙箱,跟IE一样,IE就是改变了他的代码,在Flash上执行,Adobe是非常理性的公司,ActiveX他就不管了。归根到底还是在于NPA被当时设计太灵活,扩展太多权限,所以从第一版Chrome上线以后,大家很不甘心,要把这个问题解决,历时四年之久,现在基本上把这个问题结束了。现在新的思想就是提供一个新的PPAPI,这个PPAPI包括插件用的脚本,也包括插件系统里面的API,我都在PPAPI给你提供API,简单来说就是提供了一个Crss platform,有了这个之后,整个插件工程就可以像Render一样,放在沙箱的,所以PPAPI设计思想很简单,比较直截了当,就是我给你提供很全的API,既有系统所要的API去交互需要的,你就不要调别的,就直接从浏览器,你插件不能干别的事。你只能调PPAPI。这里我简单举一个例子,比如说他提供的文件,你不能调系统的CreatefileEX,初始化系统传一个列表,你能调的API就调这个就行了,就代替你直接调系统的文件操作。

这个PPAPI提出来之后,很显然插件不会花这个精力改这个,所以当时和adobe有一个协议,我替Flash改,现在什么进展,就是说历时大概两三年之久,改完了,现在就是从Chrome21起开始,这个PPAPI Flash默认启用。

最后回顾一下,设计思想实际上有四点,第一个就是降权,按最小权限执行,同时实行隔离,在做的其中,实践上注意两点,就是利用系统内置安全性比较好,另外在安全性和可用性或者是性能上达到一个平衡。

代码贡献

最后我说说谁在做Chrome,主要是Google,但是360现在也在开源代码中也提了很多代码,从一开始提了一些BUG,现在有一些核心代码已经加进去了。谢谢大家。

更多精彩内容,请点击:SyScan360国际前瞻信息安全会议





    网友评论(共0条评论)..
    奇虎360技术总监任寰:Chrome安全架构的进化

    更多热门活动

      更多热门招聘职位