Charlie Reis | d66e0bd | 2022-06-07 17:24:12 | [diff] [blame] | 1 | # Process Model and Site Isolation |
| 2 | |
| 3 | As the early Web matured, web sites evolved from simple documents to active |
| 4 | programs, changing the web browser's role from a simple document renderer to an |
| 5 | operating system for programs. Modern browsers like Chromium use multiple |
| 6 | operating system processes to manage this workload, improving stability, |
| 7 | security, and performance. |
| 8 | |
| 9 | Chromium's **process model** determines how documents, workers, and other web |
| 10 | content are divided into processes. First, the process model must identify |
| 11 | which parts of a "program" on the web need to coexist in a single process. |
| 12 | Somewhat surprisingly, a program on the web is not a single document plus its |
| 13 | subresources, but rather a group of same (or similar) origin documents that can |
| 14 | fully access each other's contents. Once these atomic groups are defined, the |
| 15 | process model can then decide which groups will share a process. These |
| 16 | decisions can be tuned based on platform, available resources, etc, to achieve |
| 17 | the right level of isolation for different scenarios. |
| 18 | |
| 19 | This document outlines the goals and design of Chromium's process model and the |
| 20 | various ways it is used today, including its support for Site Isolation. |
| 21 | |
| 22 | [TOC] |
| 23 | |
| 24 | |
| 25 | ## Goals |
| 26 | |
| 27 | At a high level, Chromium aims to use separate processes for different instances |
| 28 | of web sites when possible. A **web site instance** is a group of documents or |
| 29 | workers that must share a process with each other to support their needs, such |
| 30 | as cross-document scripting. (This roughly corresponds to an "[agent |
| 31 | cluster](https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-cluster-formalism)" |
| 32 | from the HTML Standard, as described below.) |
| 33 | |
| 34 | For stability, putting web site instances in separate processes limits the |
| 35 | impact of a renderer process crash or hang, allowing other content to continue |
| 36 | working. For performance, this allows different web site instances to run in |
| 37 | parallel with better responsiveness, at the cost of some memory overhead for |
| 38 | each process. |
| 39 | |
| 40 | For security, strictly using separate processes for different web sites allows |
| 41 | significantly stronger defenses against malicious web sites. In addition to |
| 42 | running web content within a low-privilege |
| 43 | [sandbox](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox.md) |
| 44 | that limits an attacker's access to the user's machine, Chromium's |
| 45 | multi-process architecture can support [Site |
| 46 | Isolation](https://www.chromium.org/Home/chromium-security/site-isolation), |
| 47 | where each renderer process is only allowed to access data from a single site. |
| 48 | Site Isolation involves: |
| 49 | |
| 50 | * **Locked Renderer Processes**: A renderer process can be limited to documents |
| 51 | and workers from a single web site or origin, even if such documents are in |
| 52 | iframes. |
| 53 | * **Browser-Enforced Restrictions**: The privileged browser process can monitor |
| 54 | IPC messages from locked processes to limit their actions or access to site |
| 55 | data (e.g., using ChildProcessSecurityPolicy::CanAccessDataForOrigin). |
| 56 | This [prevents compromised renderer |
| 57 | processes](https://chromium.googlesource.com/chromium/src/+/main/docs/security/compromised-renderers.md) |
| 58 | from asking for cross-site data, using permissions granted to other sites, |
| 59 | etc. |
| 60 | * **Network Response Limitations**: Chromium can ensure that locked renderer |
| 61 | processes are only allowed to receive sensitive data (e.g., HTML, XML, |
| 62 | JSON) from their designated site or origin, while still allowing |
| 63 | cross-origin subresource requests (e.g., images, media) as needed for |
| 64 | compatibility. This is achieved using [Cross-Origin Read |
| 65 | Blocking](https://www.chromium.org/Home/chromium-security/corb-for-developers) |
| 66 | (CORB) or [Opaque Response Blocking](https://github.com/annevk/orb) (ORB). |
| 67 | |
| 68 | |
| 69 | ## Abstractions and Implementations |
| 70 | |
| 71 | Chromium uses several abstractions to track which documents and workers need |
| 72 | synchronous access to each other, as a constraint for process model decisions. |
| 73 | |
| 74 | * **Security Principal** (implemented by |
| 75 | [SiteInfo](https://source.chromium.org/chromium/chromium/src/+/main:content/browser/site_info.h;drc=c79153d6f931dbe2ce2c992962512eaca6766623;l=22)): |
| 76 | In security terminology, a **principal** is an entity with certain |
| 77 | privileges. Chromium associates a security principal with execution |
| 78 | contexts (e.g., documents, workers) to track which data their process is |
| 79 | allowed to access. This principal is typically a |
| 80 | "[site](https://html.spec.whatwg.org/multipage/origin.html#site)" (i.e., |
| 81 | scheme plus eTLD+1, such as `https://example.com`), because web pages can |
| 82 | modify their document.domain value to access other same-site documents, and |
| 83 | not just same-origin documents. In some cases, though, the principal may be |
| 84 | an origin or have a coarser granularity (e.g., `file:`). The SiteInfo class |
| 85 | tracks all values that identify a security principal. |
| 86 | |
| 87 | * **Principal Instance** (implemented by |
| 88 | [SiteInstance](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/site_instance.h;drc=858df4ab8b73f2418f51385954760f2154512029;l=32)): |
| 89 | A principal instance is the core unit of Chromium's process model. Any two |
| 90 | documents with the same principal in the same browsing context group |
| 91 | (see below) must live in the same process, because they have synchronous |
| 92 | access to each other's content. This access includes cross-document |
| 93 | scripting and synchronous communication through shared memory (e.g., |
| 94 | SharedArrayBuffer). If such documents were in different processes, data |
| 95 | races or deadlocks would occur if they concurrently accessed objects in |
| 96 | their shared DOM or JavaScript heaps. |
| 97 | |
| 98 | This roughly corresponds to the [agent |
| 99 | cluster](https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-cluster-formalism) |
| 100 | concept in the spec, although they do not match exactly: multiple agent |
| 101 | clusters may sometimes share a principal instance (e.g., with `data:` URLs |
| 102 | in the same principal instance as their creator), and principals may keep |
| 103 | track of more factors than [agent cluster |
| 104 | keys](https://html.spec.whatwg.org/multipage/webappapis.html#agent-cluster-key) |
| 105 | (e.g., whether the StoragePartition differs). |
| 106 | |
| 107 | Note that the user may visit multiple instances of a given principal in the |
| 108 | browser, sometimes in unrelated tabs (i.e., separate browsing context |
| 109 | groups). These separate instances do not need synchronous access to each |
| 110 | other and can safely run in separate processes. |
| 111 | |
| 112 | * **Browsing Context Group** (implemented by |
| 113 | [BrowsingInstance](https://source.chromium.org/chromium/chromium/src/+/main:content/browser/browsing_instance.h;drc=df269acf8de952b68b2fbec49365457ff1f6266b;l=34)): |
| 114 | A browsing context group is a group of tabs and frames (i.e., containers of |
| 115 | documents) that have references to each other (e.g., frames within the same |
| 116 | page, popups with window.opener references, etc). Any two documents within |
| 117 | a browsing context group may find each other by name, so it is important |
| 118 | that any same-principal documents in the group live in the same process. In |
| 119 | other words, there is only one principal instance per principal in a given |
| 120 | browsing context group. Note that a tab may change its browsing context |
| 121 | group on some types of navigations (e.g., due to a |
| 122 | Cross-Origin-Opener-Policy header, browser-initiated cross-site |
| 123 | navigations, and other reasons). |
| 124 | |
| 125 | From an implementation perspective, Chromium keeps track of the SiteInstance of |
| 126 | each RenderFrameHost, to determine which renderer process to use for the |
| 127 | RenderFrameHost's documents. SiteInstances are also tracked for workers, such |
| 128 | as ServiceWorker or SharedWorkerHost. |
| 129 | |
| 130 | |
| 131 | ## Modes and Availability |
| 132 | |
| 133 | ### Full Site Isolation (site-per-process) |
| 134 | |
| 135 | _Used on: Desktop platforms (Windows, Mac, Linux, ChromeOS)._ |
| 136 | |
| 137 | In (one-)site-per-process mode, each process is locked to documents from a |
| 138 | single site. Sites are defined as scheme plus eTLD+1, since different origins |
| 139 | within a given site may have synchronous access to each other if they each |
| 140 | modify their document.domain. This mode provides all sites protection against |
| 141 | compromised renderers and Spectre-like attacks, without breaking backwards |
| 142 | compatibility. |
| 143 | |
| 144 | This mode can be enabled on Android using |
| 145 | `chrome://flags/#enable-site-per-process`. |
| 146 | |
| 147 | |
| 148 | ### Partial Site Isolation |
| 149 | |
| 150 | _Used on: Chrome for Android (2+ GB RAM)._ |
| 151 | |
| 152 | On platforms like Android with more significant resource constraints, Chromium |
| 153 | only uses dedicated (locked) processes for some sites, putting the rest in |
| 154 | unlocked processes that can be used for any web site. (Note that there is a |
| 155 | threshold of about 2 GB of device RAM required to support any level of Site |
| 156 | Isolation on Android.) |
| 157 | |
| 158 | Locked processes are only allowed to access data from their own site. Unlocked |
| 159 | processes can generally access data from any site that does not require a |
| 160 | locked process. Chromium usually creates one unlocked process per browsing |
| 161 | context group. |
| 162 | |
| 163 | Currently, several heuristics are used to isolate the sites that are most likely |
| 164 | to have user-specific information. As on all platforms, privileged pages like |
| 165 | WebUI are always isolated. Chromium also isolates sites that users tend to log |
| 166 | into in general, as well as sites on which a given user has entered a password, |
| 167 | logged in via an OAuth provider, or encountered a Cross-Origin-Opener-Policy |
| 168 | (COOP) header. |
| 169 | |
| 170 | |
| 171 | ### No Site Isolation |
| 172 | |
| 173 | _Used on: Low-memory Chrome for Android (<2 GB RAM), Android WebView, Chrome for |
| 174 | iOS, Chrome Apps `<webview>`._ |
| 175 | |
| 176 | On some platforms, Site Isolation is not available, due to implementation or |
| 177 | resource constraints. |
| 178 | |
| 179 | * On Android devices with less than 2 GB of RAM, Site Isolation is disabled to |
| 180 | avoid requiring multiple renderer processes in a given tab (for out-of-process |
| 181 | iframes). Cross-process navigations in the main frame are still possible |
| 182 | (e.g., for browser-initiated cross-site navigations with no other pages in the |
| 183 | browsing context group, when a new browsing context group may be created). |
| 184 | * Android WebView does not yet support multiple renderer processes or |
| 185 | out-of-process iframes. |
| 186 | * Chrome for iOS uses WebKit, which does not currently have support for |
| 187 | out-of-process iframes or Site Isolation. |
| 188 | * The `<webview>` tag in Chrome Apps does not yet support Site Isolation. See |
| 189 | bug [1267977](https://crbug.com/1267977). |
| 190 | |
| 191 | |
| 192 | ### Origin Isolation |
| 193 | |
| 194 | _Available on: Desktop platforms, Chrome for Android (2+ GB RAM)._ |
| 195 | |
| 196 | There are several optional ways to lock processes at an origin granularity |
| 197 | rather than a site granularity, with various tradeoffs for compatibility |
| 198 | (e.g., breaking pages that modify document.domain). These are available on |
| 199 | platforms that support some level of Site Isolation. |
| 200 | |
| 201 | * **Built-in**: //content embedders can designate particular origins that |
| 202 | require isolation from the rest of their site, using |
| 203 | ContentBrowserClient::GetOriginsRequiringDedicatedProcess. |
| 204 | * **Configurable**: Users and administrators can list particular origins that |
| 205 | should be isolated from the rest of their site, using the command line |
| 206 | (`--isolate-origins=`...), `chrome://flags#isolate-origins`, or |
| 207 | [enterprise policy](https://support.google.com/chrome/a/answer/7581529) |
| 208 | ([IsolateOrigins](https://chromeenterprise.google/policies/#IsolateOrigins) |
| 209 | or |
| 210 | [IsolateOriginsAndroid](https://chromeenterprise.google/policies/#IsolateOriginsAndroid)). |
| 211 | * **Opt-in**: The [Origin-Agent-Cluster](https://web.dev/origin-agent-cluster) |
| 212 | HTTP response header can be used by web developers to hint to the browser |
| 213 | that an origin locked process can be used. This is not a security guarantee |
| 214 | and may not always be honored (e.g., to keep all same-origin documents |
| 215 | consistent within a given browsing context group), though it allows finer |
| 216 | grained isolation in the common case. Note that there are plans to enable |
| 217 | [Origin-Agent-Cluster by default](https://github.com/mikewest/deprecating-document-domain), |
| 218 | effectively disabling changes to document.domain. |
| 219 | |
| 220 | |
| 221 | ### CrossOriginIsolated |
| 222 | |
| 223 | Certain powerful web platform features now require an opt-in |
| 224 | [CrossOriginIsolated](https://web.dev/coop-coep/) mode, which ensures that all |
| 225 | cross-origin content (e.g., documents and workers, as well as subresources like |
| 226 | media or scripts) consents to being loaded in the same process as an origin |
| 227 | using these features. This opt-in is required because these powerful features |
| 228 | (e.g., SharedArrayBuffers) can be used for very precise timing, which can make |
| 229 | attacks that leak data from the process (e.g., using Spectre or other transient |
| 230 | execution attacks) more effective. This mode is important because not all |
| 231 | browsers support out-of-process iframes for cross-origin documents, and not all |
| 232 | cross-origin subresources can be put in a separate process. |
| 233 | |
| 234 | CrossOriginIsolated mode requires the main document to have |
| 235 | Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers. These |
| 236 | headers impose restrictions on all content that may load within the page or |
| 237 | process (e.g., requiring similar headers on subframes, and CORS, CORP, or a |
| 238 | credentialless mode for subresources). |
| 239 | |
| 240 | |
| 241 | ### Historical Modes |
| 242 | |
| 243 | Before Site Isolation was introduced, Chromium initially supported a few other |
| 244 | process models that affected the number of renderer processes. |
| 245 | |
| 246 | * **Process-per-site-instance**: This model was the default when Chromium first |
| 247 | launched. It used a new process when navigating to a different site in some |
| 248 | scenarios (e.g., via the address bar but not link clicks), as well as when |
| 249 | visiting different instances of the same site in different tabs. At the |
| 250 | time, cross-site subframes stayed in the same process as their parent |
| 251 | frames. |
| 252 | * **Process-per-site**: This model consolidated all instances of a given site |
| 253 | into a single process (per profile), to reduce the process count. It |
| 254 | generally led to poor usability when a single process was used for too many |
| 255 | tabs. This mode is still used for certain limited cases (e.g., the New Tab |
| 256 | Page) to reduce the process count and process creation latency. It is also |
| 257 | used for extensions to allow synchronous scripting from a background page. |
| 258 | Note that having a single process for a site might not be guaranteed (e.g., |
| 259 | due to multiple profiles, or races). |
| 260 | * **Process-per-tab**: This model used a separate process for each browsing |
| 261 | context group (i.e., possibly multiple related tabs), but did not attempt |
| 262 | to switch processes on cross-site navigations. In practice, though, this |
| 263 | model still needed to swap processes for privileged pages like `chrome://` |
| 264 | URLs. |
| 265 | * **Single process**: Chromium also allows a single process model which runs all |
| 266 | of the browser and renderer code in a single OS process. This is generally |
| 267 | not a safe or robust process model, since it prevents the use of the |
| 268 | sandbox and cannot survive any crash in renderer process code. It is mainly |
| 269 | used for older low-resource Android WebView scenarios, and for debugging or |
| 270 | testing. |
| 271 | |
| 272 | |
| 273 | ## Visualizations |
| 274 | |
| 275 | Chromium provides several ways to view the current state of the process model: |
| 276 | |
| 277 | * **Chromium's Task Manager**: This can be found under "More Tools" in the menu, |
| 278 | and shows live resource usage for each of Chromium's processes. The Task |
| 279 | Manager also shows which documents and workers are grouped together in a |
| 280 | given process: only the first row of a given group displays process ID and |
| 281 | most statistics, and all rows of a group are highlighted when one is |
| 282 | clicked. Note that double clicking any row attempts to switch to the tab it |
| 283 | is associated with. In the default sort order (i.e., when clicking the Task |
| 284 | column header until the up/down triangle disappears), processes for |
| 285 | subframes are listed under the process for their tab when possible, |
| 286 | although this may not be possible if subframes from multiple tabs are in a |
| 287 | given process. |
| 288 | * **`chrome://process-internals/#web-contents`**: This is an internal diagnostic |
| 289 | page which shows information about the SiteInstances and processes for each |
| 290 | open document. |
| 291 | * **`chrome://discards/graph`**: This is an internal diagnostic page that |
| 292 | includes a visualization of how the open documents and workers map to |
| 293 | processes. Clicking on any node provides more details. |
| 294 | |
| 295 | |
| 296 | ## Process Reuse |
| 297 | |
| 298 | For performance, Chromium attempts to strike a balance between using more |
| 299 | processes to improve parallelism and using fewer processes to conserve memory. |
| 300 | There are some cases where a new process is always required (e.g., for a |
| 301 | cross-site page when Site Isolation is enabled), and other cases where |
| 302 | heuristics can determine whether to create a new process or reuse an old one. |
| 303 | Generally, process reuse can only happen in suitable cases, such as within a |
| 304 | given profile or respecting a process lock. Several factors go into this |
| 305 | decision. |
| 306 | |
| 307 | * **Suitability**: Several properties are global to a given renderer process: |
| 308 | profile (including Incognito), StoragePartition (which may differ between |
| 309 | tabs and Chrome Apps), and crossOriginIsolated status. For example, two |
| 310 | documents from different profiles or StoragePartitions can never share the |
| 311 | same renderer process. The ProcessLock (described below) also restricts |
| 312 | which documents are allowed in a process. |
| 313 | * **Soft Process Limit**: On desktop platforms, Chromium sets a "soft" process |
| 314 | limit based on the memory available on a given client. While this can be |
| 315 | exceeded (e.g., if Site Isolation is enabled and the user has more open |
| 316 | sites than the limit), Chromium makes an attempt to start randomly reusing |
| 317 | same-site processes when over this limit. For example, if the limit is 100 |
| 318 | processes and the user has 50 open tabs to `example.com` and 50 open tabs to |
| 319 | example.org, then a new `example.com` tab will share a process with a random |
| 320 | existing `example.com` tab, while a chromium.org tab will create a 101st |
| 321 | process. Note that Chromium on Android does not set this soft process |
| 322 | limit, and instead relies on the OS to discard processes. |
| 323 | * **Aggressive Reuse**: For some cases (including on Android), Chromium will |
| 324 | aggressively look for existing same-site processes to reuse even before |
Adithya Srinivasan | c8e3d59 | 2022-07-15 13:27:28 | [diff] [blame] | 325 | reaching the process limit. Out-of-process iframes (OOPIFs) and [fenced |
| 326 | frames](https://developer.chrome.com/en/docs/privacy-sandbox/fenced-frame/) |
| 327 | use this approach, such that an `example.com` iframe in a cross-site page |
| 328 | will be placed in an existing `example.com` process (in any browsing context |
| 329 | group), even if the process limit has not been reached. This keeps the |
| 330 | process count lower, based on the assumption that most iframes/fenced frames |
| 331 | are less resource demanding than top-level documents. Similarly, |
| 332 | ServiceWorkers are generally placed in the same process as a document that |
| 333 | is likely to rely on them. |
Charlie Reis | d66e0bd | 2022-06-07 17:24:12 | [diff] [blame] | 334 | * **Extensions**: Chromium ensures that extensions do not share a process with |
| 335 | each other or with web pages, but also that a large number of extensions |
| 336 | will not consume the entire soft process limit, forcing same-site web pages |
| 337 | into too few processes. Chromium only allows extensions to consume [one |
| 338 | third](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc;drc=8d6a246c9be4f6b731dc7f6e680b7d5e13a512b5;l=454-458) |
| 339 | of the process limit before disregarding further extension processes from |
| 340 | the process limit computation. |
| 341 | * **Process-per-site**: As noted above, pages like the New Tab Page (NTP) and |
| 342 | extensions use a model where all instances of the page are placed in the |
| 343 | same process. |
| 344 | |
| 345 | |
| 346 | ## Process Locks |
| 347 | |
| 348 | Chromium assigns a |
| 349 | [ProcessLock](https://source.chromium.org/chromium/chromium/src/+/main:content/browser/process_lock.h;drc=47457a6923c0527261d0503998cbeb7de9bab489;l=19) |
| 350 | to some or all RenderProcessHosts, to restrict which sites are allowed to load |
| 351 | in the process and which data the process has access to. A RenderProcessHost is |
| 352 | an object in the browser process that represents a given renderer process, |
| 353 | though it can be reused if that renderer process crashes and is restarted. Some |
| 354 | ProcessLock cases are used on all platforms (e.g., `chrome://` URLs are never |
| 355 | allowed to share a process with other sites), while other cases may depend on |
| 356 | the mode (e.g., Full Site Isolation requires all processes to be locked, once |
| 357 | content has been loaded in the process). |
| 358 | |
| 359 | ProcessLocks may have varying granularity, such as a single site |
| 360 | (e.g., `https://example.com`), a single origin |
| 361 | (e.g., `https://accounts.example.com`), an entire scheme (e.g., `file://`), or |
| 362 | a special "allow-any-site" value for processes allowed to host multiple sites |
| 363 | (which may have other restrictions, such as whether they are |
| 364 | crossOriginIsolated). RenderProcessHosts begin with an "invalid" or unlocked |
| 365 | ProcessLock before one is assigned. |
| 366 | |
| 367 | ProcessLocks are always assigned before any content is loaded in a renderer |
| 368 | process, either at the start of a navigation or at OnResponseStarted time, just |
| 369 | before a navigation commits. Note that a process may initially receive |
| 370 | an "allow-any-site" lock for some empty document schemes (e.g., `about:blank`), |
| 371 | which may later be refined to a site-specific lock when the first actual |
| 372 | content commits. Once a site-specific lock is assigned, it remains constant for |
| 373 | the lifetime of the RenderProcessHost, even if the renderer process itself |
| 374 | exits and is recreated. |
| 375 | |
| 376 | Note that content may be allowed in a locked process based on its origin |
| 377 | (e.g., an `about:blank` page with an inherited `https://example.com` origin is |
| 378 | allowed in a process locked to `https://example.com`). Also, some opaque origin |
| 379 | cases are allowed into a locked process as well, such as `data:` URLs created |
| 380 | within that process, or same-site sandboxed iframes. |
| 381 | |
| 382 | |
| 383 | ## Special Cases |
| 384 | |
| 385 | There are many special cases to consider in Chromium's process model, which may |
| 386 | affect invariants or how features are designed. |
| 387 | |
| 388 | * **WebUI**: Pages like `chrome://settings` are considered part of Chromium and |
| 389 | are highly privileged, usually hosted in the `chrome://` scheme. They are |
| 390 | strictly isolated from non-WebUI pages as well as other types of WebUI |
| 391 | pages (based on "site"), on all platforms. They are also generally not |
| 392 | allowed to load content from the network (apart from a shrinking |
| 393 | [list](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc;drc=3344b61f7c7f06cf96069751c3bd64d8ec3e3428;l=1405) |
| 394 | of allowlisted pages), unless it is from a separate unprivileged |
| 395 | `chrome-untrusted://` document. Additionally, normal web pages are not |
| 396 | allowed to navigate to WebUI pages, which makes privilege escalation |
| 397 | attacks more difficult. |
| 398 | * **New Tab Page**: On desktop platforms, the default "local" NTP is a WebUI |
| 399 | page using process-per-site mode, which loads content from the network via |
| 400 | `chrome-untrusted://` iframes. Third party NTPs are also possible, which |
| 401 | load a "remote" non-WebUI web page with limited privileges. On Android, the |
| 402 | NTP is instead a native Android surface with no privileged renderer |
| 403 | process. Chrome on Android creates an unused renderer process in the |
| 404 | background while the NTP surface is visible, so that the next page can use |
| 405 | it. |
| 406 | * **Extensions**: On desktop platforms, extension documents and workers are |
| 407 | semi-privileged and run in dedicated renderer processes. In contrast, |
| 408 | extension content scripts run within the same unprivileged web renderer |
| 409 | process as the pages they modify, and thus Chrome Extensions need to |
| 410 | [treat content scripts as less |
| 411 | trustworthy](https://groups.google.com/a/chromium.org/g/chromium-extensions/c/0ei-UCHNm34/m/lDaXwQhzBAAJ). |
| 412 | The browser process makes an effort to enforce that renderer processes have |
| 413 | access to any extension APIs or capabilities that they attempt to use. |
| 414 | * **Hosted Apps**: A hosted app is a deprecated type of extension which allows a |
| 415 | normal web site to have a special type of renderer process. For example, a |
| 416 | hosted app for `https://example.com/app/` will have an "effective URL" that |
| 417 | looks like a `chrome-extension://` URL, causing it to be treated |
| 418 | differently in the process model. This support may eventually be removed. |
| 419 | * **Chrome Web Store**: The [Chrome Web |
| 420 | Store](https://chrome.google.com/webstore) is a rare example of a privileged |
| 421 | web page, to which Chrome grants special APIs for installing extensions. |
| 422 | This implementation currently relies on hosted apps. |
| 423 | * **GuestView**: The Chrome Apps `<webview>` tag and similar cases like |
| 424 | MimeHandlerView and ExtensionOptionsGuest embed one WebContents within |
| 425 | another. These may use a different process model, such as `<webview>` not |
| 426 | yet supporting Site Isolation. (See bug |
| 427 | [1267977](https://crbug.com/1267977).) Note that Chrome Apps allow |
| 428 | `<webview>` tags to load normal web pages and the app's own `data:` or |
| 429 | `chrome-extension://` URLs, but not URLs from other extensions or apps. |
| 430 | * **Sandboxed iframes**: Documents with the sandbox attribute and without |
| 431 | `allow-same-origin` (either iframes or popups) may be same-site with their |
| 432 | parent or opener but use an opaque origin. Chromium currently keeps these |
| 433 | documents in the same process as their parent or opener, but this may |
| 434 | change in bug [510122](https://crbug.com/510122). |
| 435 | * **`data:` URLs**: Chromium generally keeps documents with `data:` URLs in the |
| 436 | same process as the site that created them, since that site has control |
| 437 | over their content. The exception is when restoring a previous session, in |
| 438 | which case each document with a `data:` URL ends up in its own process. |
| 439 | * **File URLs**: Chromium currently treats all `file://` URLs as part of the |
| 440 | same site. Normal web pages are not allowed to load `file://` URLs, and |
| 441 | renderer processes are only granted access to particular `file://` URLs via |
| 442 | file chooser dialogs (e.g., for uploads). These URLs may be further isolated |
| 443 | from each other in bug [780770](https://crbug.com/780770). |
| 444 | * **Error Pages**: Chromium uses a special type of process for error pages |
| 445 | provided by the browser (as opposed to error pages provided by a web site, |
| 446 | like a 404 page), using process-per-site mode to keep all such pages in the |
| 447 | same process. Currently this only applies to error pages in a main frame. |
| 448 | * **Spare Process**: Chromium often creates a spare RenderProcessHost with a |
| 449 | live but unlocked renderer process, which is used the next time a renderer |
| 450 | process is needed. This avoids the need to wait for a new process to |
| 451 | start. |
| 452 | * **Android WebView**: While Android WebView uses much of the same code as |
| 453 | Chromium, it currently only supports a single renderer process in most |
| 454 | cases. |
| 455 | |
| 456 | |
| 457 | ## Further Reading |
| 458 | |
| 459 | Several academic papers have covered topics about Chromium's process model. |
| 460 | |
| 461 | [**Security Architecture of the Chromium |
Eric Lawrence | 6d32301 | 2022-06-07 18:53:56 | [diff] [blame] | 462 | Browser**](https://crypto.stanford.edu/websec/chromium/) |
Charlie Reis | d66e0bd | 2022-06-07 17:24:12 | [diff] [blame] | 463 | |
| 464 | Adam Barth, Collin Jackson, Charles Reis, and The Google Chrome Team. Stanford |
| 465 | Technical Report, September 2008. |
| 466 | |
| 467 | _Abstract:_ |
| 468 | |
| 469 | Most current web browsers employ a monolithic architecture that combines "the |
| 470 | user" and "the web" into a single protection domain. An attacker who exploits |
| 471 | an arbitrary code execution vulnerability in such a browser can steal sensitive |
| 472 | files or install malware. In this paper, we present the security architecture |
| 473 | of Chromium, the open-source browser upon which Google Chrome is built. |
| 474 | Chromium has two modules in separate protection domains: a browser kernel, |
| 475 | which interacts with the operating system, and a rendering engine, which runs |
| 476 | with restricted privileges in a sandbox. This architecture helps mitigate |
| 477 | high-severity attacks without sacrificing compatibility with existing web |
| 478 | sites. We define a threat model for browser exploits and evaluate how the |
| 479 | architecture would have mitigated past vulnerabilities. |
| 480 | |
| 481 | [**Isolating Web Programs in Modern Browser |
| 482 | Architectures**](https://research.google.com/pubs/archive/34924.pdf) |
| 483 | |
| 484 | Charles Reis, Steven D. Gribble (both authors at UW + Google). Eurosys, |
| 485 | April 2009. |
| 486 | |
| 487 | _Abstract:_ |
| 488 | |
| 489 | Many of today's web sites contain substantial amounts of client-side code, and |
| 490 | consequently, they act more like programs than simple documents. This creates |
| 491 | robustness and performance challenges for web browsers. To give users a robust |
| 492 | and responsive platform, the browser must identify program boundaries and |
| 493 | provide isolation between them. |
| 494 | |
| 495 | We provide three contributions in this paper. First, we present abstractions of |
| 496 | web programs and program instances, and we show that these abstractions clarify |
| 497 | how browser components interact and how appropriate program boundaries can be |
| 498 | identified. Second, we identify backwards compatibility tradeoffs that |
| 499 | constrain how web content can be divided into programs without disrupting |
| 500 | existing web sites. Third, we present a multi-process browser architecture that |
| 501 | isolates these web program instances from each other, improving fault |
| 502 | tolerance, resource management, and performance. We discuss how this |
| 503 | architecture is implemented in Google Chrome, and we provide a quantitative |
| 504 | performance evaluation examining its benefits and costs. |
| 505 | |
| 506 | [**Site Isolation: Process Separation for Web Sites within the |
| 507 | Browser**](https://www.usenix.org/conference/usenixsecurity19/presentation/reis) |
| 508 | |
| 509 | Charles Reis, Alexander Moshchuk, and Nasko Oskov, Google. Usenix Security, |
| 510 | August 2019. |
| 511 | |
| 512 | _Abstract:_ |
| 513 | |
| 514 | Current production web browsers are multi-process but place different web sites |
| 515 | in the same renderer process, which is not sufficient to mitigate threats |
| 516 | present on the web today. With the prevalence of private user data stored on |
| 517 | web sites, the risk posed by compromised renderer processes, and the advent of |
| 518 | transient execution attacks like Spectre and Meltdown that can leak data via |
| 519 | microarchitectural state, it is no longer safe to render documents from |
| 520 | different web sites in the same process. In this paper, we describe our |
| 521 | successful deployment of the Site Isolation architecture to all desktop users |
| 522 | of Google Chrome as a mitigation for process-wide attacks. Site Isolation locks |
| 523 | each renderer process to documents from a single site and filters certain |
| 524 | cross-site data from each process. We overcame performance and compatibility |
| 525 | challenges to adapt a production browser to this new architecture. We find that |
| 526 | this architecture offers the best path to protection against compromised |
| 527 | renderer processes and same-process transient execution attacks, despite |
| 528 | current limitations. Our performance results indicate it is practical to deploy |
| 529 | this level of isolation while sufficiently preserving compatibility with |
| 530 | existing web content. Finally, we discuss future directions and how the current |
| 531 | limitations of Site Isolation might be addressed. |