这个文档描述了Chromium支持的不同线程模型,包括它的渲染器进程,以及现有模型实现的问题。
网页内容已经发展到包含大量在浏览器内运行的活跃代码的地步,使得许多网站更像应用程序而非文档。这种变革改变了浏览器的角色,从一个简单的文档渲染器变成一个操作系统。Chromium构建得像一个操作系统那样,使用多进程隔离每个网站和浏览器自身,以一种安全而鲁棒的方式运行这些程序。这提高了鲁棒性,因为每个进程运行在自己的地址空间里,由操作系统调度,即使崩溃也不会互相影响。用户也可以在Chromium的任务管理器里查看每个进程的资源使用情况。
Web浏览器有许多方法可以分割成不同的操作系统进程,最佳的架构的选择取决于许多因素,包括稳定性,资源使用,对实际情况的观察。Chromium支持四种不同的进程模型,允许开发者实验,也有最适合大部分用户的默认模式。
Chromium支持四种不同的模型,它们影响浏览器分配页面给渲染进程的行为。默认情况下,Chromium为用户访问的每个网站使用一个独立的操作系统进程。然而,用户可以在启动Chromium时指定命令行选项,以选择其他的架构:全网站单进程,每组相连标签页一个进程,或者每个东西都放在一个单独的进程中。这些模型的区别在于他们是否影响内容的源,是否影响标签页间的关系,或者两者都会影响。这个章节在更深的细节上讨论每种模型,并在这个文档的后面描述当前Chromium的实现的一些问题。
默认情况下,Chromium为用户访问的每个网站实例创建一个渲染器进程。这保证了不同网站的网页独立渲染,让对同一个网站的不同访问相互独立。因此一个网站实例中的失败(比如,渲染器崩溃)或者重的资源使用不会影响浏览器的其他部分。这个模型基于内容的源和脚本会相互影响的标签页间的关系。因此,两个标签页可以在同一个渲染进程里展示页面,同时在给定的一个标签页中导航到网站外的一个网页,可能切换标签页的渲染进程。(注意,Chromium当前的实现有一些重要的问题,会在下面的Caveat(警告)部分讨论。)
具体说来,我们把一个注册域名(例如:google.com或bbc.co.uk)加一个scheme(例如:https:// )定义为一个网站。这与同源策略定义相似,但它将子域名(比如:mail.google.com和docs.google.com)和端口(比如http://foo.com:8080 )合并到同一个网站中。允许网站的不同子域名或端口中的页面通过Javascript访问是有必要的,如果他们的document.domain变量相同的话,同源策略也会这样允许。
一个网站实例是一些相同网站的相连网页的集合。我们这样认为两个页面是相连的:如果他们可以在脚本代码中获取彼此的引用的话(比如:如果一个页面被另一个页面用Javascript在一个新窗口中打开)。
优点
缺点
Chromium也支持这样一种进程模式,隔离不同的网站,但将相同网站的所有实例组合到一块。为了使用这个模型,用户需要在启动Chromium时在终端指定 --process-per-site开关。这创建更少的渲染进程,用鲁棒性交换更少的内存占用。这个模型基于内容的源,而非标签页间的关系。
优点
隔离不同网站的内容。正如每个网站实例一个进程的模型那样,不同网站的页面不会共享命运(不会同生共死。。)。
缺点
每个网站或每个网站实例一个进程都需要在创建渲染进程时考虑网站内容的源。Chromium也支持一种简单的模型,将一个渲染器进程分配给每组脚本相关的标签页。这个模型可以使用 --process-per-tab命令行开关来选中。
特别地,我们会把一些脚本相关联的标签页成为一个浏览实例,它也与HTML5范畴中的“一个浏览上下文单元”对应。这个集合由一个标签以及这个标签用javascript代码所打开的标签组合而成。这样的标签必须在同一个进程中渲染,以允许在这些标签页间执行javascript调用(大多数通常发生在同源页面之间)。
优点
缺点
某些情况下,尽管处于安全的需要,在这个模型中,Chromium仍然强制标签页中的进程交换已经没有什么价值。例如,通常的网页不允许与优先级高的网页(比如设置,或者新标签页)共享进程。因此,这个模型在实践中并没有比单个网站实例单进程更简单。
最后,出于比较的目的,Chromium支持单进程模型,通过--single-process命令行开关打开。在这个模型中,浏览器和渲染引擎跑在同一个操作系统进程里。
单进程模型提供了一个衡量多进程架构带来的负荷的基线。这不是一个安全的架构,也不是一个鲁棒的架构,因为任何渲染器的崩溃会导致整个浏览器进程挂掉。它只是设计用于测试和开发目的,并且可能包含在其他架构中没有的bug。
在每个多进程架构里,Chromium的渲染器进程运行在一个沙箱进程中,它对用户电脑只有有限的访问权限。这些进程对用户的文件系统,显示器,或者大部分其他的资源没有直接的接触。相反,他们只通过浏览器进程获得对允许的资源的访问,而浏览器进程可以在这种访问上附加安全策略。因此,Chromium的浏览器进程可以减轻一个被利用的渲染器引擎能做的事情。
浏览器插件,比如Flash和Silverlight,也在他们自己的进程中执行,并且有些插件,比如Flash运行在Chromium的沙箱中。在Chromium支持的每个多进程架构中,对每种活跃的插件都只有一个进程。因此,所有的Flash实例运行在同一个进程里,不论它们出现在哪个网站或标签页中。
这个部分列出一些Chromium当前进程模型实现的警告,以及它们的意义。
然而,网页可以使用一种机制来让一个链接指向一个不相关的页面,这样它们可以在不同的进程中安全地渲染。如果一个link有rel=noreferrer或target=blank这样的属性,那么Chromium会在另外的进程中渲染它。
子页面现在是与父页面在相同进程中渲染的。虽然跨站点的子页面没有访问它们的父页面的脚本,而且它们可以在不同的进程中安全地渲染,但Chromium还没有在独立的进程中渲染它们。与上面的第一个警告相似,这意味着不同站点的页面会在同样的进程中渲染。这很可能在Chromium将来的版本中进行修改。
Chromium中有两个类代表了不同的进程模型实现的抽象需要:BrowsingInstance和SiteInstance。
BrowsingInstance类代表了一个浏览器中脚本相连的集合,在HTML5领域中也被称为相关浏览上下文单元。在单标签页单进程模型中,我们为每个BrowsingInstance创建一个渲染器进程。
SiteInstance类代表了来自相同站点的相同页面。它是BrowsingInstance内部页面的一个子集,因为在BrowsingInstance内部,每个站点只有一个SiteInstance,所以它很重要。在单网站实例单进程模型中,我们为每个SiteInstance创建一个渲染器进程。为了实现单网站单进程,我们必须确保来自同一个站点的所有的SiteInstance归入相同的进程中。
Charles Reis, Steven D. Gribble (both authors at UW + Google)
Eurosys 2009. Nuremberg, Germany, April 2009.
摘要
今天的许多网站包含大量客户端代码,因此,他们不再是简单的文档,而更多地表现出程序的特征。这给浏览器提出了鲁棒性与性能的挑战。为了给用户提供一个鲁棒而又快速响应的平台,浏览器必须识别应用程序边界,在他们之间提供隔离。
我们在这篇文章中提出三个点。第一,我们为web程序和程序实例提供抽象,并说明这些抽象描绘了浏览器组件是如何交互的,合适的程序边界该如何识别出来;第二,我们识别回退可用性的代价,因为这约束了在不干扰已有网站的情况下,将网页内容划分为程序所能做到的程度;第三,我们展示了一个多进程浏览器架构,相互隔离这些web应用程序,提高容错度,优化资源管理和性能。我们会讨论这个架构在Google Chrome中是如何实现的,然后我们会提供一个量化的性能评估以检查这种架构的好处与代价。
Chromium浏览器安全架构
Adam Barth, Collin Jackson, Charles Reis, and The Google Chrome Team
Stanford Technical Report, September 2008.
摘要
大多数当前网页浏览器使用一个单片架构,将user和web合并到同一个保护域中。如果一个攻击者在这样的浏览器中利用了任意一个代码执行漏洞,他们都可以盗取敏感文件或者安装恶意软件。在这篇文章里,我们会展示Chromium(Google Chrome是在这个开源软件的基础上构建的)的安全架构。Chromium有两个处于不同保护域中的模块:一个是浏览器内核,与操作系统交流,一个是渲染引擎,在沙箱中运行,有着有限的权限。这个架构能够减轻高危攻击,而且不牺牲已有网站的可用性。我们为每个浏览器调用定义了一个威胁模型,并评估这个架构能够如何减少过去的漏洞。