In 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.
In general, content coming from the network is considered untrustworthy, regardless of the source and transport protocol.
Examples of trustworthy content include, the contents ofchrome://version
which are populated entirely within the browser process, the contents ofchrome://about
which is a hardcoded list of URLs, etc.
It 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 tochrome://
, e.g. process isolation, but it won’t be default-granted extra capabilities that are default-granted tochrome://
.
The-untrusted
suffix indicates that theWebUI processes untrustworthy content. For example, rendering an image provided by users, parsing a PDF file, etc.
The-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.
chrome-untrusted://
acts as a technical and semantic boundary between fully-trusted WebUIs and untrustworthy WebUIs.
Technical because developers can usechrome-untrusted://
to separate their WebUIs into two origins e.g.chrome://media-app
andchrome-untrusted://media-app
with access to different capabilities, resources, etc.
Semantic because it indicates to chromium developers and security reviewers that a WebUI is meant to process untrustworthy content and shouldn’t be granted dangerous capabilities.
Historically,chrome://
pages have been built with the assumption that they are an extension to the browser process, sochrome://
web pages are granted special capabilities not granted to ordinary web pages. For example, allchrome://
pages can use Web APIs like camera and mic without requesting permission.
Some WebUIs would like to be able to process untrustworthy content, but granting these capabilities to achrome://
page would violate therule of 2:
chrome://
page is considered an extension to the browser processBy usingchrome-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 compromisedchrome-untrusted://
page is no worse than an ordinary web page.
chrome-untrusted://
re-uses a lot of the code that backschrome://
pages, so it doesn’t impose a big maintenance burden; even then, our hope is to one day remove all default granted capabilities based on thechrome://
scheme to the point that the difference betweenchrome://
andchrome-untrusted://
WebUIs is just a semantic one (see previous point).
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.
Today, the main use case is when we want to have code that ships with Chrome work with untrustworthy content that comes over the network.
Yes. “Content” in this context also includes code.
Yes, but not by default and with some caveats.
Any team that requires extra capabilities granted tochrome-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.
We recommend using Mojo to expose APIs tochrome-untrusted://
. Mojo forchrome-untrusted://
works similarly to how it works forchrome://
with a few key differences:
chrome://
pages,chrome-untrusted://
pages don't get access to all renderer exposed Mojo interfaces by default. UsePopulateChromeWebUIFrameInterfaceBrokers
to expose WebUI specific interfaces to your WebUI. Seethis CL for example.chrome-untrusted://
page could try to exploit the interface (e.g. sending malformed messages, closing the Mojo pipe).When exposing extra capabilities tochrome-untrusted://
, keep in mind:
We also recommend using Mojo to communicate between parent and child frames whenever possible. Seethis CL for example.
You should only usepostMessage()
when transferring objects unsupported by Mojo. For example, Media App usespostMessage()
to pass a read-onlyFileSystemHandle
file handle tochrome-untrusted://media-app
from its parentchrome://media-app
.
We encourage teams to engage withSECURITY_OWNERS early and get the reviews required.
chrome://
page?Yes,chrome-untrusted://
can be the main document, although the most common case is for achrome://
page to embed achrome-untrusted://
subframe.
That said, thechrome-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 usechrome-untrusted://
as the main document.
ui::WebUIConfig
and another one overridingui::UntrustedWebUIController
WebUIConfig
contains properties for thechrome-untrusted://
page i.e. the host and scheme. In the future, this might also contain other properties like permissions or resources.
UntrustedWebUIController
register the resources for the page.
constchar kUntrustedExampleHost[]="untrusted-example";constchar kUntrustedExampleURL[]="chrome-untrusted://untrusted-example";classUntrustedExampleUIConfig:public content::WebUIConfig{public:UntrustedExampleUIConfig()// Set scheme and host.:WebUIConfig(content::kChromeUIUntrustedScheme, kUntrustedExampleHost){}~UntrustedExampleUIConfig() override=default; std::unique_ptr<content::WebUIController>CreateWebUIController( content::WebUI* web_ui) override{return std::make_unique<UntrustedExampleUI>(web_ui);}};classUntrustedExampleUI:public ui::UntrustedWebUIController{public:UntrustedExampleUI::UntrustedExampleUI(content::WebUI* web_ui): ui::UntrustedWebUIController(web_ui){// Create a URLDataSource and add resources.auto* untrusted_source= content::WebUIDataSource::CreateAndAdd( web_ui->GetWebContents()->GetBrowserContext(), kUntrustedExampleURL); untrusted_source->AddResourcePath(...);}UntrustedExampleUI(constUntrustedExampleUI&)=delete;UntrustedExampleUI&operator=(constUntrustedExampleUI&)=delete;UntrustedExampleUI::~UntrustedExampleUI()=default;};
Add theWebUIConfig
to the appropriate list of WebUIConfigs inchrome_untrusted_web_ui_configs
.
register_config(std::make_unique<chromeos::UntrustedExampleUIConfig>());
Developers can embedchrome-untrusted://
iframes inchrome://
pages.Example CL.
The general steps are:
chrome-untrusted://
page.chrome://
WebUI to embed the correspondingchrome-untrusted://
WebUI.untrusted_data_source->AddFrameAncestor(kWebUIPageURL)
chrome-untrusted://
requestable by the mainchrome://
WebUI.web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme)
chrome://
WebUI to embed chrome-untrusted://.trusted_data_source->OverrideContentSecurityPolicy(“frame-src”+ kUntrustedExampleURL);
chrome-untrusted://
frames. For example,using Mojo, orpostMessage
the JavaScript object is not supported by Mojo.