blob: e4ed08ec4e430cb1376366debe6c84e9cd230a35 [file] [log] [blame] [view]
Lukasz Anforowiczf4e58ce2020-05-11 18:18:581# Compromised Renderers
2
3Given the complexity of the browser, our threat model must use a "defense
4in depth" approach to limit the damage that occurs if an attacker
5finds a way around the Same Origin Policy or other security logic in the
6renderer process.
7For example, the combination of Chrome's sandbox, IPC security checks, and Site
8Isolation limit what an untrustworthy renderer process can do. They
9protect Chrome users against attackers, even when such attackers are able to
10bypass security logic in the renderer process.
11For other motivations for the "defense in depth" approach and why our
12threat model covers compromised renderers, please see the
13[document here](https://www.chromium.org/Home/chromium-security/site-isolation#TOC-Motivation).
14
15In a compromised renderer, an attacker is able to execute
16arbitrary native (i.e. non-Javascript) code within the renderer
17process's sandbox. A compromised renderer can forge
18malicious IPC messages, impersonate a Chrome Extension content script,
19or use other techniques to trick more privileged parts of the browser.
20
21The document below gives an overview of features that Chrome attempts to
22protect against attacks from a compromised renderer. Newly discovered
23holes in this protection would be considered security bugs and possibly
24eligible for the
25[Chrome Vulnerability Rewards Program](https://www.google.com/about/appsecurity/chrome-rewards/).
26
27[TOC]
28
29
30## Site Isolation foundations
31
32Most of the other protections listed in this document implicitly assume that
33attacker-controlled execution contexts (e.g. HTML documents or service workers)
34are hosted in a separate renderer process from other, victim contexts.
35This separation is called
36[Site Isolation](https://www.chromium.org/Home/chromium-security/site-isolation)
37and allows the privileged browser
38process to restrict what origins a renderer process is authorized to read or
39control.
40
41The privilege restriction can be implemented in various ways - see the
42"protection techniques" listed in other sections in this document.
43One example is validating in the browser process whether an incoming IPC can
44legitimately claim authority over a given origin (e.g. by checking via
45`CanAccessDataForOrigin` if the process lock matches).
46Another example is making sure that capabilities handed over to renderer
47processes are origin-bound (e.g. by setting `request_initiator_site_lock`
48on a `URLLoaderFactory` given to renderer processes).
49Yet another example is making security decisions based on trustworthy knowledge,
50calculated within the privileged browser process (e.g. using
51`RenderFrameHost::GetLastCommittedOrigin()`).
52
53Compromised renderers shouldnt be able to commit an execution context into a
54renderer process hosting cross-site execution contexts.
55On desktop platforms all sites (eTLD+1) should be isolated from each other.
56On Android, sites where the user entered a password should be isolated
57from each other and from other sites.
58
59**Known gaps in protection**:
60- No form of Site Isolation is active in Android WebView
61 See also https://crbug.com/769449.
62- No form of Site Isolation is active in content hosted within
63 `<webview>` HTML tags. See also https://crbug.com/614463.
64- Frames with `<iframe sandbox>` attribute are not isolated
65 from their non-opaque precursor origin.
66 See also https://crbug.com/510122.
67- `file:` frames may share a process with other `file:` frame.
68 See also https://crbug.com/780770.
69
70
71## Cross-Origin HTTP resources
72
73Compromised renderers shouldn't be able to read the contents (header + body) of
74a cross-site HTTP response, unless it is a valid subresource needed for
75compatibility (e.g., JavaScript, images, etc), or is successfully allowed via
76CORS.
77
78Protection techniques:
79- Enforcing
80 [Cross-Origin Read Blocking
81 (CORB)](https://www.chromium.org/Home/chromium-security/corb-for-developers)
82 in the NetworkService process
83 (i.e. before the HTTP response is handed out to the renderer process).
84- Only allowing the privileged browser process to create
85 `network::mojom::URLLoaderFactory` objects that handle HTTP requests.
86 This lets the browser process carefully control security-sensitive
87 `network::mojom::URLLoaderFactoryParams` of such factories (such as
88 `request_initiator_site_lock`, `is_corb_enabled`, `disable_web_security` or
89 `isolation_info`).
90 This also lets the CORB implementation in the NetworkService process
91 prevent spoofing of `network::ResourceRequest::request_initiator`
92 by using `network::GetTrustworthyInitiator` for comparison with
93 the trustworthy `request_initiator_site_lock`.
94
95**Known gaps in protection**:
96- Content types for which CORB does not apply
97 (e.g. `image/png`, `application/octet-stream`) are not protected by
98 default. We recommend that HTTP servers protect such resources by
99 either serving a `Cross-Origin-Resource-Policy: same-origin` response header
100 or validating the `Sec-Fetch-Site` request header.
101- CORB protection is relaxed in presence of
102 - Adobe Flash plugin (see https://crbug.com/874515)
103 - A relatively small number of allowlisted Chrome Extensions
104 (see https://crbug.com/846346)
105
106
107## Contents of cross-site frames
108
109Compromised renderers shouldn't be able to read the contents of cross-site
110frames. Examples:
111- Text or pixels of cross-site frames.
112- Full URL of cross-site frames. Note that the origin part is okay
113 since it is already exposed via `window.origin`.
114
115Protection techniques:
116- Compositing tab contents (both for display and for printing)
117 outside the renderer processes.
118- Isolating PDF plugins.
119- Being careful what URLs are exposed in console messages.
120
121**Known gaps in protection**:
122- Mixed content console messages may disclose cross-site URLs
123 (see also https://crbug.com/726178).
124
125
126## Cookies
127
128Compromised renderers shouldnt be able to read or write
129any cookies of another site,
130or `httpOnly` cookies even from the same site.
131
132Protection techniques:
133- Renderer processes are only given `network::mojom::RestrictedCookieManager`
134 for origins within their site
135 (see `StoragePartitionImpl::CreateRestrictedCookieManager`).
136- Mojo serialization does not send any cookies from HTTP headers to the renderer
137 process (see
138 `ParamTraits<scoped_refptr<net::HttpResponseHeaders>>::Write`).
139
140
141## Passwords
142
143Compromised renderers shouldnt be able to read or write passwords of
144other sites.
145
146Protection techniques:
147- Using `CanAccessDataForOrigin` to verify IPCs sent by a renderer process
148 (e.g. `//components/password_manager/content/browser/bad_message.cc`)
149- Using trustworthy, browser-side knowledge
150 to determine which credentials to read or write
151 (e.g. `content::RenderFrameHost::GetLastCommittedURL` in
152 `password_manager::CredentialManagerImpl::GetOrigin`).
153
154
155## Security-sensitive UI/chrome elements (e.g. Omnibox)
156
157Compromised renderers shouldnt be able to influence/spoof
158security-sensitive UI elements.
159
160Examples:
161- Omnibox
162 - URL (e.g. renderer process locked to foo.com shouldnt
163 be able to trick the Omnibox into displaying bar.com)
164 - Secure / not secure chip (e.g. a renderer process locked to a HTTP
165 site shouldnt be able to trick the Omnibox into displaying a
166 HTTPS-associated lock)
167 - Content settings (e.g. a renderer process that has been granted
168 microphone access shouldnt be able to suppress the mic/camera
169 icon in the Omnibox)
170- Dialogs and prompts (for example a permissions dialog asking to allow
171 a site to show notifications)
172 - Origin in dialogs (e.g. a renderer process locked to foo.com
173 shouldnt be able to trick the Omnibox into displaying a bar.com
174 URL in permission dialogs)
175
176Protection techniques:
177- `RenderFrameHostImpl::CanCommitOriginAndUrl` verifies that the renderer
178 process is able to commit what it claims, and kills the process otherwise.
179- Work-in-progress: calculating the origin in the browser process,
180 before a navigation commits (https://crbug.com/888079).
181
182
183## Permissions
184
185Compromised renderers shouldnt be able to gain permissions without user
186consent.
187
188Examples: microphone access permission, geolocation permission, etc.
189
190Protection techniques:
191- Requesting permissions based on browser-side knowledge of frame's origin
192 (e.g. see `GeolocationServiceImplContext::RequestPermission`).
193
194
195## Web storage
196
197Compromised renderers shouldn’t be able to read from or write into
198storage of another site.
199
200Examples of protected storage technologies:
201- localStorage
202- sessionStorage
203- indexedDB
204- blob storage
205- webSQL
206
207Protection techniques:
208- Using CanAccessDataForOrigin to verify IPCs sent by a renderer process
209 (e.g. see `StoragePartitionImpl::OpenLocalStorage`).
210- Binding mojo interfaces to a single origin obtained from browser-side
211 information in `RenderFrameHost::GetLastCommittedOrigin()`
212 (e.g. see RenderFrameHostImpl::CreateIDBFactory).
213
214**Known gaps in protection**:
215- https://crbug.com/917457: FileSystem API (deprecated, Chrome-only).
216
217
218## Messaging
219
220Compromised renderers shouldn’t be able to:
221- Spoof the `MessageEvent.origin` seen by a recipient of a `postMessage`.
222- Bypass enforcement of the `targetOrigin` argument of `postMessage`.
223- Send or receive BroadcastChannel messages for another origin.
224- Spoof the `MessageSender.origin` seen by a recipient of a
225 `chrome.runtime.sendMessage`
226 (see also [MessageSender documentation](https://developers.chrome.com/extensions/runtime#type-MessageSender) and [content script security guidance](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/0ei-UCHNm34)).
227
228Protection techniques:
229- Using CanAccessDataForOrigin to verify IPCs sent by a renderer process
230 (e.g. in `RenderFrameProxyHost::OnRouteMessageEvent` or
231 `BroadcastChannelProvider::ConnectToChannel`).
232
233**Known gaps in protection**:
234- Spoofing of `MessageSender.id` object
235 (see [here](https://developers.chrome.com/extensions/runtime#type-MessageSender)
236 and https://crbug.com/982361).
237
238
239## Javascript code cache
240
241Compromised renderers shouldn't be able to poison the Javascript code cache
242used by scripts executed in cross-site execution contexts.
243
244Protection techniques:
245- Partitioning the code cache by Network Isolation Key (NIK).
246- Using `CanAccessDataForOrigin` in
247 `CodeCacheHostImpl::DidGenerateCacheableMetadataInCacheStorage`.
248
249
250## Cross-Origin-Resource-Policy response header
251
252A compromised renderer shouldnt be able to bypass
253Cross-Origin-Resource-Policy (CORS),
254which prevents or allows responses from being requested cross-origin, more
255explicitly than CORB.
256
257Protection techniques:
258- Enforcing Cross-Origin-Resource-Policy in the NetworkService process
259 (i.e. before the HTTP response is handed out to the renderer process).
260- Preventing spoofing of `network::ResourceRequest::request_initiator`
261 by using `network::GetTrustworthyInitiator` which enforces
262 browser-controlled `request_initiator_site_lock`.
263
264
265## Frame-ancestors CSP and X-Frame-Options response headers
266
267A compromised renderer shouldnt be able to bypass `X-Frame-Options`
268or `frame-ancestors` CSP.
269
270For example, if example.com/page.html sends a `X-Frame-Options: deny` header,
271then it should never commit in a subframe, even if some renderers have
272been compromised.
273
274Protection techniques:
275- `X-Frame-Options: deny` is enforced in the browser process
276 via `content::AncestorThrottle`, an implementation of
277 `content::NavigationThrottle`.
278- `frame-ancestors` is enforced in a renderer process, but
279 this process is considered trustworthy in this scenario
280 (because it hosts the frame that is requesting protection).
281 See also https://crbug.com/759184 which tracks
282 moving this enforcement into the browser process.
283
284
285## HTTP request headers
286
287Compromised renderers shouldnt be able to control security sensitive HTTP
288request headers like `Host` or `Sec-Fetch-Site`.
289
290Protection techniques:
291- Using `AreRequestHeadersSafe` to reject `Host` and other headers that
292 should only be generated internally within the NetworkService.
293- `Sec-Fetch-Site` is robust against spoofing of
294 `network::ResourceRequest::request_initiator` by using
295 `network::GetTrustworthyInitiator` which enforces browser-controlled
296 `request_initiator_site_lock`.
297
298**Known gaps in protection**:
299- `Origin` header. Tracked by
300 https://crbug.com/920634 (making
301 `network::ResourceRequest::request_initiator` unspoofable without
302 having to go through `GetTrustworthyInitiator`) and
303 https://crbug.com/920638 (making
304 `network::ResourceRequest::isolated_world_origin` irrelevant for
305 security decisions).
306
307
308## (WIP) SameSite cookies
309
310Compromised renderers shouldnt be able to send a cross-site HTTP request with
311SameSite cookies.
312
313**Work-in-progress / not protected today**.
314
315TODO(morlovich): Add details. I assume that this requires trustworthy
316|request_initiator| (similar to the `Origin` header), but probably more
317than that.
318
319See also https://crbug.com/927967.
320
321
322## (WIP) User gestures / activations.
323
324Compromised renderers shouldn't be able to spoof user gestures to perform
325actions requiring them.
326
327**Work-in-progress / not protected today**. See https://crbug.com/848778.
328
329
330## Web Accessible Resources of Chrome Extensions
331
332Compromised non-extension renderers shouldn’t be able to access
333non-web-accessible-resources of a Chrome Extension.
334
335Protection techniques:
336- Navigations: Enforcement in the browser process
337 via `extensions::ExtensionNavigationThrottle`, an implementation of
338 `content::NavigationThrottle`. This relies on non-spoofability
339 of `content::NavigationHandle::GetInitiatorOrigin`.
340- Subresources: Enforcement in the browser process via
341 `ExtensionURLLoaderFactory::CreateLoaderAndStart`. This relies
342 on process boundaries and therefore doesn't rely on non-spoofability
343 of `network::ResourceRequest::request_initiator`.
344
345
346## Non-Web resources
347
348Compromised *web* renderer processes shouldnt be able to access
349*local* resources (e.g. `file://...` or `chrome://settings`).
350
351Protection techniques:
352- TODO(lukasza, nasko): need to research
353
354
355## Android-specific protection gaps
356
357Due to resource constraints, on Android platforms only some sites get a
358dedicated renderer process, isolated from other sites.
359(Current heuristic is to isolate the sites where the user has entered a password
360in the past.)
361This means that some sites are hosted in a renderer process that is
362*not* locked to any particular site. If an attacker compromises
363an unlocked renderer process, they may try to abuse protection gaps listed
364below.
365
366**Known gaps in protection**:
367- When `CanAccessDataForOrigin` runs on the IO thread, it cannot protect
368 isolated sites against being accessed from an unlocked renderer process.
369 Some web storage protections depend on `CanAccessDataForOrigin` calls
370 on the IO thread.
371 See also https://crbug.com/764958.
372- `request_initiator_site_lock` may be missing in unlocked renderer
373 processes on Android (for example affecting protections of CORB, CORP,
374 Sec-Fetch-Site and in the future SameSite cookies and Origin
375 protections). See also https://crbug.com/891872.