New issue
Advanced search Search tips
Starred by 3 users

Issue metadata

Status: Started
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Sign in to add a comment

Issue 871827: CORB shouldn't trust the renderer (e.g. shouldn't trust ResourceRequest::request_initiator)

Reported by, Aug 7 Project Member

Issue description

AFAICT, ResourceRequest::request_initiator today:

1) can originate from the renderer (e.g. see ChildURLLoaderFactoryBundle::CreateLoaderAndStart or ResourceFetcherImpl::ClientImpl::Start)

2) is not validated in the NetworkService and/or the browser process (e.g. see URLLoaderFactory::CreateLoaderAndStart and the constructor of URLLoader).

This means that a compromised renderer can just lie about the request_initiator to bypass CORB.

Comment 1 by, Aug 7


Comment 2 by, Aug 7

Blockedon: 846346
Currently CORB makes an exception for content script and this exception is based on checking the initiator's scheme (and comparing it against chrome-extension://).  This probably means that this bug is blocked on issue 846346 (which talks about having a separate URLLoaderFactory for content scripts - one with a separate initiator and/or separate CORB exceptions).

Comment 3 by, Sep 19

Status: Started (was: Untriaged)
A partial attempt to lock down the request initiator is here:

Comment 4 by, Sep 25

+alexmos@ who is investigating whether html imports 1) from 2) of components, would use VS in their Origin header and/or network::ResourceRequest::request_initiator field when making requests on behalf of the component.

Comment 5 by, Sep 25

Blockedon: 888079
The default URLLoaderFactory for a frame is created at ready-to-commit time.  If we wanted to lock such factory to a specific request_initiator origin, then it would have to be done at ready-to-commit time.  The problem is that today, the browser process doesn't know which origin will commit - fixing this depends on the "precursor origin" work.

Comment 6 by, Sep 26

#4: the test I was investigating here was http/tests/htmlimports/import-script-block-crossorigin-dynamic.html.  IIUC, the test works as follows (sample cmdline to run it at [1]):

1. Starts running at and gets locked to this origin when running with --site-per-process.
2. Does a html import for http://localhost:8000/htmlimports/resources/cors-having-crossorigin-scripts.cgi.  This is allowed to go through because the response has Access-Control-Allow-Origin:
3. The html import dynamically injects three external scripts into the imported document (i.e., into document.currentScript.ownerDocument, distinct from document that was loaded in step 1).  
4. These scripts are all at and differ in their CORS responses: 
  a. has no CORS headers
  b. has "Access-Control-Allow-Origin:".
  c. has "Access-Control-Allow-Origin: http://localhost:8000"
5. The test expects scripts (a) and (b) to *fail* loading, and (c) to succeed.

For all three scripts, the network request comes through with a network::ResourceRequest::request_initiator of "http://localhost:8000", while in a process locked to

I'm concerned how this affects computing the request_initiator in the browser process, like in comment #3: it seems a renderer for can include html imports from arbitrary sites which can then pose as request initiators.

[1] third_party/blink/tools/ --additional-driver-flag=--site-per-process --no-show-results --driver-logging -t <your_out_dir> http/tests/htmlimports/import-script-block-crossorigin-dynamic.html

Comment 7 by, Sep 26

Maybe some good news re: #6: according to, HTML Imports are deprecated at M70 and will be removed in M73.

Comment 8 by, Oct 3

Blockedon: 891872

Comment 9 by, Nov 14

Blockedon: 766694
+yoichio@ who AFAIK works on deprecation of HTML imports in M73 (per and

HTML imports make it difficult to realize full security benefits of Site Isolation, because even if a renderer process is locked to a single site (say it may still issue subresource requests for another site (say because of HTML imports.

Going forward, I'd like to have Cross-Origin Read Blocking (CORB) depend on the trustworthy |request_initiator_origin_lock| (being introduced in instead of depending on untrustworthy |request_initiator| coming from the renderer.  This seems likely to break a scenario where uses a HTML import from and the import tries to use fetch API to fetch CORB-protected resource (e.g. JSON or XML) from (I assume that such fetch is possible via HTML imported scripts + that the fetch would be considered same-origin and wouldn't require CORS).  If CORB depends on |request_initiator_origin_lock| then it would block the JSON/XML response from, because the request would be initiated from a process locked to

Given above, I hope deprecation of HTML imports can proceed as planned (i.e. without any further delays).  Looking at the deprecation thread, I see that while the feature is planned to be deprecated in M73, it will still be available via reverse origin trials until 2020Q1 - this makes me sad (I'll try to think if any workarounds are possible for CORB;  any suggestions are welcome).

Comment 10 by, Nov 15

The fact that HTML Imports can cause a security issue is a significant motivation to deprecate the feature though the usage is still high.

Thanks for the investigation.

Comment 11 by, Nov 15

Removing Restrict-View-Google - there is no sensitive information in the bug.  In particular, this bug tracks a step needed to implement a *new* security feature / *new* security guarantees (rather than tracking a security bug in an existing security feature / guarantee).

Comment 12 by, Nov 20

Note to self (and to nasko@): I've verified that subresource requests made from a sandboxed frame use request_initiator set to an opaque/unique origin.


0. Add ad-hoc logging to network::URLLoader's constructor to log request_initiator
   Launch Chrome with --enable-features=NetworkService

1. Navigate to

2. In DevTools, in main frame:
     var frame = document.createElement('iframe')
     frame.sandbox = "allow-scripts"

3. In DevTools, in the new subframe:
     window.origin  // optional: verify that the frame has opaque/unique/null origin
     // verify that CORS + CORB kick-in (and observe the request_initiator):
          .then(() => console.log('success'))
          .catch(e => console.log('error: ' + e));

     // verify that CORB kicks in (and observe the request_initiator):
     fetch('', {mode: "no-cors"})
          .then(() => console.log('success'))
          .catch(e => console.log('error: ' + e));


A. CORS + CORB are kicking in
B. request_initiator is set to an opaque/unique/null origin:

    [] URLLoader::ctor; request.url =; request_initiator = null [internally: (EE9A09A...186365) anonymous]

Comment 13 by, Nov 26

Blocking: 515309

Comment 14 by, Nov 28

This bug is marked as being blocked by issue 888079 (Browser process should calculate the origin to commit).  Let me expand that a little bit below.

Main problem is that at the time of RenderFrameHostImpl::CommitNavigation, the browser process needs to know or compute request_initiator_origin_lock to be used by the default URLLoaderFactory that will be sent down to the renderer process as part of the commit IPC.  This is problematic in case of about:blank pages - the origin they will commit with is currently not known until DidCommit IPC from the renderer.

Examples of about:blank navigations that go through RenderFrameHostImpl::CommitNavigation and need to commit with a non-opaque origin:
- FrameTreeBrowserTest.NavigateChildToAboutBlank a frame uses'about:blank', 'targetFrame') to navigate its remote frame to about:blank (in origin).
- NavigationControllerBrowserTest.FrameNavigationEntry_BackWithRedirect navigates to about:blank during a browser-initiated "back" navigation.

Therefore, until precursor origins and issue 888079 are resolved, RenderFrameHostImpl::CommitNavigation may need to continue falling back to the site URL:

1. Note that without site-per-process site URL is an okay fallback for current code (e.g. for deciding whether to turn CORB on or off), but is *not* a good fallback for |request_initiator_origin_lock|:

1.1. For example may commit in a process associated with SiteInstance (difference in scheme and hostname is intentional) - in this case we don't want enforce requests from by treating them as if they came from an opaque origin).

1.2. Another example is process reuse for extensions (we don't want to stamp an opaque request_initiator, because that may break OOR-CORS that needs to look at extension-specific CORS exemptions).

1.3. We may consider working around that by only enforcing |request_initiator_origin_lock| on desktop platforms (ignoring switches::kDisableSiteIsolation) - not sure if this is a good option.

2. Also note that the network service is not able to translate |request_initiator| into a site URL.  This means that the enforcement of |request_initiator_origin_lock| will need to be relaxed (e.g. limited to scheme-equality checks and eTLD+1 checks for http/https locks).

Comment 15 by, Nov 29

Blockedon: 910287

Comment 16 by, Dec 7

Project Member
The following revision refers to this bug:

commit 1e686969e6098169e9306ae8cbc245e80c416dad
Author: Lukasz Anforowicz <>
Date: Fri Dec 07 01:14:19 2018

Introducing URLLoaderFactoryParams::request_initiator_origin_lock.

This CL is a step toward the world where we don't trust the origin
reported by the renderer in network::ResourceRequest::request_initiator
and instead know the request initiator a priori (e.g. it gets computed
by the browser process).

This CL only logs UMA that says whether the newly introduced lock is
compatible with the request initiator requested by the user of the
NetworkService (e.g. by the renderer process).  This CL doesn't yet
enforce the request_initiator_origin_lock - the enforcement will be
enabled in a separate, follow-up CL.

This CL builds upon the fact that in most cases
RenderProcessHostImpl::CreateURLLoaderFactory knows which origin will
use the factory to initiate requests.  In presence of NetworkService,
this knowledge allows locking of URLLoaderFactory to this specific

The only cases where the origin is not known should eventually disappear
after is dealt with.  Note that CL has to deal
with the fact that because of sometimes only a
site URL (rather than origin) may be known at the commit time.  This is
why the lock is temporarily called |request_initiator_site_lock| rather
than |request_initiator_origin_lock|.

Bug: 871827
Change-Id: I97cc8285ace65e072bd7780da45522b10cb5ba57
Commit-Queue: Łukasz Anforowicz <>
Reviewed-by: Brian White <>
Reviewed-by: Devlin <>
Reviewed-by: John Abd-El-Malek <>
Reviewed-by: Nasko Oskov <>
Cr-Commit-Position: refs/heads/master@{#614535}

Comment 17 by, Dec 11

Blockedon: 914130

Comment 18 by, Dec 21

Labels: -Restrict-View-Google
Hmmm... in #c11 I wanted to remove Restrict-View-Google, but didn't actually do it... :-/

Comment 19 by, Jan 3

Project Member
The following revision refers to this bug:

commit 2d3f85193a309457c923e1edc053c5d7a9d214e6
Author: Lukasz Anforowicz <>
Date: Thu Jan 03 06:39:30 2019

Enforce |request_initiator_site_lock| for Cross-Origin Read Blocking.

In the long-term we want |request_initiator_site_lock| to take
precedence over |request_initiator| everywhere in the NetworkService.
This is risky however, because there are known cases where
|request_initiator| may differ from |request_initiator_site_lock| even
without a malicious/compromised renderer in the picture (e.g. HTML
Imports).  Therefore, in the short-term, we start with enforcing
|request_initiator_site_lock| only for Cross-Origin Read Blocking
(CORB) - this is safer because:
- CORB only applies to a subset of requests and so this approach seems
  safer and okay to enable by default (while measuring the impact via UMA
  and having a kill switch ready).
- CORB is only web-observable when blocking subresource requests
  trigerred by XHR/fetch API (and these requests seem to always use a
  |request_initiator| compatible with |request_initiator_site_lock|;
  this is covered by new tests added by this CL).

Bug: 871827
Change-Id: If9459bfbd09411d70c3547de0e50a58832e75503
Commit-Queue: Łukasz Anforowicz <>
Reviewed-by: John Abd-El-Malek <>
Reviewed-by: Ilya Sherman <>
Reviewed-by: Nasko Oskov <>
Cr-Commit-Position: refs/heads/master@{#619597}

Comment 20 by, Jan 3

Blockedon: -891872 -888079
We've found good workarounds and so this issue is no longer blocked by issue 888079 and issue 891872 (there issues only block switching from site to origin, but they don't block CORB enforcement / unbypassability).  I've opened a separate bug to track switching to using an origin instead of site - issue 918967.

Comment 21 by, Jan 4

The CL in #c19 (Enforce |request_initiator_site_lock| for Cross-Origin Read Blocking) landed in 73.0.3661.0.  We should monitor the newly added SiteIsolation.XSD.NetworkService.InitiatorLockCompatibility for the next few weeks.

Comment 22 by, Jan 7

SiteIsolation.XSD.NetworkService.InitiatorLockCompatibility shows that BlockingWhenIncorrectLock is non-zero as expected - this is probably caused by HTML Imports using <script> or <img> tag that points to non-script/non-image.  The impact is very low though:
- BlockingWhenIncorrectLock is <0.5% of BenignBlocking+BlockingWhenCompatibleLock
- BlockingWhenIncorrectLock is <0.005% of NoBlocking

Comment 23 by, Jan 25

Blockedon: 925457

Comment 24 by bugdroid, Feb 21 (2 days ago)

Project Member
The following revision refers to this bug:

commit 69b8df685b0429f3e06c22a7a86c6c016abf1a31
Author: Lukasz Anforowicz <>
Date: Thu Feb 21 18:42:04 2019

Extract GetTrustworthyInitiator to remove code duplication in CORB/CORP.

This CL extracts a GetTrustworthyInitiator helper function to
deduplicate code that used to be present in CrossOriginReadBlocking and
CrossOriginResourcePolicy classes.

In the short-term future, GetTrustworthyInitiator might be used for
making security decisions in other NetworkService features (e.g. in
Sec-Fetch-Site - see bugs 872285 and 924204 as well as the spec at

In the long-term, we want to ensure that net::URLRequest::initiator
itself is trustworthy (e.g. by terminating renderers that request a
network::ResourceRequest::request_initiator that is incompatible with
request_initiator_site_lock).  This can't happen in the short-term,
because of compatibility risks associated with HTML Imports (see

Bug: 871827, 872285, 924204
Change-Id: I7a87fae7b44a82dbd55af448d228ffaad4f6dbb0
Commit-Queue: Łukasz Anforowicz <>
Reviewed-by: Charlie Reis <>
Cr-Commit-Position: refs/heads/master@{#634273}

Sign in to add a comment