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