blob: 42ca144de0bcef4fa0969d26a5922dbc6b8b36aa [file] [log] [blame] [view]
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:231# chrome-untrusted:// FAQ
2
3[TOC]
4
5## What is “untrustworthy content”?
6
7In this context, untrustworthy content is content that comes from untrustworthy sources, e.g. an image downloaded from the internet, a PDF file provided by the user, etc. Code is also considered content in this case.
8
9In general, content coming from the network is considered untrustworthy, regardless of the source and transport protocol.
10
11Examples of trustworthy content include, the contents of `chrome://version` which are populated entirely within the browser process, the contents of `chrome://about` which is a hardcoded list of URLs, etc.
12
13## What is chrome-untrusted://?
14
15It is a new scheme which can be used to serve resources bundled with Chrome and that process untrustworthy content. It has the usual protections provided to `chrome://`, e.g. process isolation, but it wont be default-granted extra capabilities that are default-granted to `chrome://`.
16
Carlos Knippschilde084bd22024-09-19 18:50:5417The `-untrusted` suffix indicates that the [WebUI](webui_explainer.md) processes untrustworthy content. For example, rendering an image provided by users, parsing a PDF file, etc.
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2318
19The `-untrusted` suffix does not mean the web page is designed to do malicious things, or users should not trust it. Instead, the `-untrusted` suffix is to signal to us, Chromium developers, that this page will process untrustworthy content, and should be assumed to be compromised, much like an ordinary renderer process.
20
21## Why do we need chrome-untrusted://?
22
23### Separate fully trusted WebUIs and untrustworthy ones
24
25`chrome-untrusted://` acts as a technical and semantic boundary between fully-trusted WebUIs and untrustworthy WebUIs.
26
27Technical because developers can use `chrome-untrusted://` to separate their WebUIs into two origins e.g. `chrome://media-app` and `chrome-untrusted://media-app` with access to different capabilities, resources, etc.
28
29Semantic because it indicates to chromium developers and security reviewers that a WebUI is meant to process untrustworthy content and shouldnt be granted dangerous capabilities.
30
31### chrome:// is too powerful to process untrustworthy content
32
33Historically, `chrome://` pages have been built with the assumption that they are an extension to the browser process, so `chrome://` web pages are granted special capabilities not granted to ordinary web pages. For example, all `chrome://` pages can use Web APIs like camera and mic without requesting permission.
34
Donghan Parkac8f6de12025-05-14 01:45:2735Some WebUIs would like to be able to process untrustworthy content, but granting these capabilities to a `chrome://` page would violate the [rule of 2](../security/rule-of-2.md):
Carlos Knippschilde084bd22024-09-19 18:50:5436
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2337 * a `chrome://` page is considered an extension to the browser process
38 * the renderer is written in an unsafe programming language (C++).
Carlos Knippschilde084bd22024-09-19 18:50:5439 * running in an privileged context:
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2340
41By using `chrome-untrusted://` we put the untrustworthy content into a sandboxed and non-privileged environment (an ordinary renderer, with no dangerous capabilities). This brings us back to safety, a compromised `chrome-untrusted://` page is no worse than an ordinary web page.
42
43`chrome-untrusted://` re-uses a lot of the code that backs `chrome://` pages, so it doesnt impose a big maintenance burden; even then, our hope is to one day remove all default granted capabilities based on the `chrome://` scheme to the point that the difference between `chrome://` and `chrome-untrusted://` WebUIs is just a semantic one (see previous point).
44
45## When is it appropriate to use chrome-untrusted://?
46
47`chrome-untrusted://` is usually used for implementing privilege separation so that processing untrustworthy content e.g. parsing JSON, displaying an image, running code from the network, etc. is done in an unprivileged context.
48
49Today, the main use case is when we want to have code that ships with Chrome work with untrustworthy content that comes over the network.
50
51## Can I use $js\_library\_from\_url?
52
53Yes. Content in this context also includes code.
54
55## Do we grant any extra capabilities to chrome-untrusted://?
56
57Yes, but not by default and with some caveats.
58
59Any team that requires extra capabilities granted to `chrome-untrusted://` should consult with the security team to ensure they are non-dangerous. In this context, we consider non-dangerous any API that we would expose to the renderer process, e.g. UMA.
60
Jiewei Qianb99170e2021-11-22 23:16:0261We recommend using Mojo to expose APIs to `chrome-untrusted://`. Mojo for `chrome-untrusted://` works similarly to how it works for `chrome://` with a few key differences:
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2362
Carlos Knippschilde084bd22024-09-19 18:50:5463* Unlike `chrome://` pages, `chrome-untrusted://` pages don't get access to all renderer exposed Mojo interfaces by default. Use `PopulateChromeWebUIFrameInterfaceBrokers` to expose WebUI specific interfaces to your WebUI. See [this CL](https://crrev.com/c/3138688/5/chrome/browser/chrome_browser_interface_binders.cc) for example.
Jiewei Qianb99170e2021-11-22 23:16:0264* The exposed interface has a different threat model: a compromised `chrome-untrusted://` page could try to exploit the interface (e.g. sending malformed messages, closing the Mojo pipe).
65
Carlos Knippschilde084bd22024-09-19 18:50:5466When exposing extra capabilities to `chrome-untrusted://`, keep in mind:
Jiewei Qianb99170e2021-11-22 23:16:0267
68* Don't grant any capabilities that we wouldn't grant to a regular renderer. For example, don't expose unrestricted access to Bluetooth devices, but expose a method that opens a browser-controlled dialog where the user chooses a device.
69* What you received (from the WebUI page) is untrustworthy. You must sanitize and verify its content before processing.
70* What you send (to the WebUI page) could be exfiltrated to the Web. Don't send sensitive information (e.g. user credentials). Only send what you actually need.
71* The difference in Mojo interface lifetimes could lead to use-after-free bugs (e.g. a page reloads itself when it shouldn't). We recommend you create and reinitialize the interface on each page load (using [WebUIPrimaryPageChanged](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/web_ui_controller.h;l=54?q=WebUIPrimaryPageChanged&ss=chromium)), and have the JavaScript bind the interface on page load.
72
Carlos Knippschilde084bd22024-09-19 18:50:5473We also recommend using Mojo to communicate between parent and child frames whenever possible. See [this CL](https://crrev.com/c/3222406) for example.
Jiewei Qianb99170e2021-11-22 23:16:0274
75You should only use `postMessage()` when transferring objects unsupported by Mojo. For example, Media App uses `postMessage()` to pass a read-only [`FileSystemHandle`](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) file handle to `chrome-untrusted://media-app` from its parent `chrome://media-app`.
76
77We encourage teams to engage with [SECURITY_OWNERS](https://source.chromium.org/chromium/chromium/src/+/main:ipc/SECURITY_OWNERS) early and get the reviews required.
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2378
79## Can chrome-untrusted:// be the main document or does it need to be embedded in a `chrome://` page?
Jiewei Qian29b8e3b92021-02-17 00:22:4280Yes, `chrome-untrusted://` can be the main document, although the most common case is for a `chrome://` page to embed a `chrome-untrusted://` subframe.
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2381
82That said, the `chrome-untrusted://` scheme is an implementation detail of the WebUI and should never be shown to users. This should be factored into account when deciding whether or not to use `chrome-untrusted://` as the main document.
83
84## How do I use chrome-untrusted://?
85
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:5486### Create a standalone chrome-untrusted:// WebUI
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:2387
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54881. Create a class overriding `ui::WebUIConfig` and another one overriding `ui::UntrustedWebUIController`
89
90`WebUIConfig` contains properties for the `chrome-untrusted://` page i.e. the host and scheme. In the future, this might also contain other properties like permissions or resources.
91
92`UntrustedWebUIController` register the resources for the page.
93
94```cpp
95const char kUntrustedExampleHost[] = "untrusted-example";
96const char kUntrustedExampleURL[] = "chrome-untrusted://untrusted-example";
97
John Palmer404a9142022-12-07 00:34:4898class UntrustedExampleUIConfig : public content::WebUIConfig {
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:5499 public:
100 UntrustedExampleUIConfig()
101 // Set scheme and host.
102 : WebUIConfig(content::kChromeUIUntrustedScheme, kUntrustedExampleHost) {}
103 ~UntrustedExampleUIConfig() override = default;
104
105 std::unique_ptr<content::WebUIController> CreateWebUIController(
106 content::WebUI* web_ui) override {
107 return std::make_unique<UntrustedExampleUI>(web_ui);
108 }
109};
110
111class UntrustedExampleUI : public ui::UntrustedWebUIController {
112 public:
113 UntrustedExampleUI::UntrustedExampleUI(content::WebUI* web_ui)
114 : ui::UntrustedWebUIController(web_ui) {
115
116 // Create a URLDataSource and add resources.
117 auto* untrusted_source =
Rebekah Pottera894942392023-01-05 18:44:13118 content::WebUIDataSource::CreateAndAdd(
119 web_ui->GetWebContents()->GetBrowserContext(), kUntrustedExampleURL);
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54120 untrusted_source->AddResourcePath(...);
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54121 }
122
123 UntrustedExampleUI(const UntrustedExampleUI&) = delete;
124 UntrustedExampleUI& operator=(const UntrustedExampleUI&) = delete;
125
126 UntrustedExampleUI::~UntrustedExampleUI() = default;
127};
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23128
129```
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54130
1312. Register the WebUIConfig
132
John Palmera6ef3282022-12-07 00:34:59133Add the `WebUIConfig` to the appropriate list of WebUIConfigs in [`chrome_untrusted_web_ui_configs`](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/webui/chrome_untrusted_web_ui_configs.cc).
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54134
135```cpp
136register_config(std::make_unique<chromeos::UntrustedExampleUIConfig>());
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23137```
138
Jiewei Qianb99170e2021-11-22 23:16:021393. If needed, implement and register the necessary Mojo interfaces. See [this CL](https://crrev.com/c/3138688/5/chrome/browser/chrome_browser_interface_binders.cc) for example.
140
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23141### Embed chrome-untrusted:// in chrome:// WebUIs
142
143Developers can embed `chrome-untrusted://` iframes in `chrome://` pages. [Example CL](https://chromium-review.googlesource.com/c/chromium/src/+/2037186).
144
145The general steps are:
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:541461. Create a WebUIConfig and UntrustedWebUIController to register the resources for the `chrome-untrusted://` page.
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:231472. Allow the `chrome://` WebUI to embed the corresponding `chrome-untrusted://` WebUI.
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54148```cpp
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23149untrusted_data_source->AddFrameAncestor(kWebUIPageURL)
150```
1513. Make `chrome-untrusted://` requestable by the main `chrome://` WebUI.
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54152```cpp
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23153web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme)
154```
1554. Allow the `chrome://` WebUI to embed chrome-untrusted://.
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54156```cpp
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23157trusted_data_source->OverrideContentSecurityPolicy(
Giovanni Ortuño Urquidi442e8b82020-12-23 03:33:54158 “frame-src ” + kUntrustedExampleURL);
Giovanni Ortuño Urquidi24dba762020-09-17 05:42:23159```
Jiewei Qianb99170e2021-11-22 23:16:021605. Add communication mechanism to `chrome-untrusted://` frames. For example, [using Mojo](https://crrev.com/c/3222406), or `postMessage` the JavaScript object is not supported by Mojo.