New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 738046 link

Starred by 4 users

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Windows , Mac
Pri: 2
Type: Feature



Sign in to add a comment

Cross-origin popup window shares main thread of parent

Reported by a...@scirra.com, Jun 29 2017

Issue description

UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3144.0 Safari/537.36

Steps to reproduce the problem:
1. Visit https://www.scirra.com/labs/bugs/popup-isolation/
2. Click 'Open cross-origin popup'
3. In the popup window, click "Hang for 3s"

What is the expected behavior?
The parent window should not hang.

What went wrong?
The parent window also hangs.

Did this work before? N/A 

Does this work in other browsers? N/A

Chrome version: 61.0.3144.0  Channel: canary
OS Version: 10.0
Flash Version: 

This affects our PWA Construct 3 (editor.construct.net). It's game development software, and the game is previewed in a cross-origin popup window. Like in this demo, we specifically clear the window.opener property, trying to reproduce the rel=noopener effect for a popup. The aim is to run the popup in its own thread, so that if the game hangs or crashes, it does not affect the editor itself. For example the user may make a mistake and set their game in to an infinite loop. However this isolation is not effective, and if the user makes a mistake, they can no longer access the editor, and may even lose their work since they can't press save any more.

I can't think of any reason a cross-origin popup window with no opener needs to run in the main thread of its parent window; it seems like a bug. The repro URL provides a few options to compare whether the opened window hangs the parent window or not.

Firefox appears to always share the main thread in all four cases. Edge impressively seems to always isolate in its own thread in all four cases.
 

Comment 1 by a...@scirra.com, Jun 29 2017

Something odd I noticed while making the repro - if I run the main index.html from disk (on file:// protocol), the cross-origin popup *is* isolated from the parent! So it seems Chrome does have this capability already, but doesn't use it...
Labels: Needs-Triage-M61

Comment 3 by kochi@chromium.org, Jun 30 2017

Cc: kochi@chromium.org
Components: Blink>SecurityFeature>CORS
Labels: -Needs-Triage-M61 M-61 OS-Linux OS-Mac
Status: Untriaged (was: Unconfirmed)
Tested on Chrome Stable #59.0.30171.115 and Canary #61.0.3147.0 on Windows 10, Mac 10.12.5 and Ubuntu 14.04 and issue is reproducible. 
 
This is a non-regression issue and able to reproduce from M-45 #45.0.2454.101. Marking it as untriaged so that issue gets addressed.
 
Thanks.

Cc: dcheng@chromium.org
Components: -Blink>SecurityFeature>CORS Blink
This is not an issue with the CORS protocol.

dcheng@, could you please help me assign this to the right person?

Comment 6 by junov@chromium.org, Jul 12 2017

Cc: junov@chromium.org
Components: -Blink Blink>WindowDialog
Labels: -Type-Bug Type-Feature
To obtain the level of isolation described in the description, I think we would need cross-origin pop-ups to get their own render process (with a separate main thread). Such behavior is not required by the spec AFAICT.

I think this is more of a feature request than a bug.

It is not clear to me whether it makes sense for a WindowProxy object to exist in a separate process from the Window that it proxies, even though the WindowProxy is mostly opaque in the cross-origin case.

Assigning to WindowDialog component for further triage.

Comment 7 by dcheng@chromium.org, Jul 17 2017

Cc: creis@chromium.org nasko@chromium.org
Components: -Blink>WindowDialog UI>Browser>Navigation
It's important to note that cross-origin doesn't mean that the resulting frame will be out-of-process. There's some internal heuristics that we use to determine whether a new window gets its own process. It's also not guaranteed that you'll get a new process if you're running up against the process limits.

The current heuristics are here: https://cs.chromium.org/chromium/src/content/renderer/render_frame_impl.cc?rcl=58ed7135967bcaefb71844a48ebfe8c2cdef045c&l=5442

As for the specific problem here:

The fact that it works when opened from a file:// URL (which has unique origin) leads me to believe that it's because the cross-origin page is merely cross-origin, and not cross-site as well. The 'site' of an origin is simply the effective TLD + 1--so something with an origin of one.two.example.com has a site of example.com Two pages are cross-site if they have different sites.

The reason we use cross-site rather than cross-origin is because two same-site pages can opt into being same-origin via document.domain, while cross-site pages can never do the same.

Also, I believe it's rel=noreferrer that gives 'fork' behavior, though I'm not sure how much of an implementation detail this is...

Comment 8 by a...@scirra.com, Jul 17 2017

Is there a way to specify rel=noreferrer with window.open? Or another way to hint at using a cross-process window? As per the original report we are trying to isolate user content from the web app to the greatest extent possible. Will we have to register a whole new site (e.g. constructpreview.net) to get that in Chrome?
Cc: mkwst@chromium.org alex...@chromium.org
#8: Try window.open(url, "", "noopener").  There is also some related discussion  in  issue 732560 .

Comment 10 by a...@scirra.com, Jul 18 2017

#9: window.open(url, "", "noopener") causes the call to return null, so you can't postMessage to the opened window, which we need for our use case. Therefore we have to use this pattern:
let win = window.open(null, null, ...);
win.opener = null;
win.location = url;
This is used in the bug report, but does not create a cross-process window. Is there another way?

Comment 11 by a...@scirra.com, Jul 18 2017

Possibly related is issue 738419 in which Chrome seems to confuse the window.opener property with the real window opener.

Comment 12 by nasko@chromium.org, Jul 18 2017

I would highly recommend to not rely on internal Chromium implementation of how process allocation works. We change the process model from time to time and there is no guarantee it will stay the same long term.

Also, Chromium, at the time of this writing, does not use origins as the granularity of isolation, but rather it uses "site" (scheme and eTLD+1 tuple) to make its decisions. So to answer #c8, you are best served by using a completely different domain (not subdomains).

Comment 13 by a...@scirra.com, Jul 18 2017

Okay, but the reason we have to play with heuristics is because AFAIK there's no explicit way to get what we want.

Comment 14 by nasko@chromium.org, Jul 18 2017

There are good reasons why there is no explicit way to influence the process model, as it cannot be guaranteed, depending on the device and platform your app is running on. Also, multiprocess didn't even exist at some point :).

Comment 15 by a...@scirra.com, Jul 18 2017

I know, but on the other hand, I believe our use case is legitimate. In game development software, a mistake in the game shouldn't take down the editor as well. It's inconvenient and causes lost work, and thus is important to our users. This is a disadvantage compared to our previous native app which we ported to the web. Modern browsers have the capability to isolate the game window in a way that prevents this, so we'll do whatever we can to get that. If there's no explicit way provided, we'll coerce the heuristics. So despite your warnings, I think our best course of action to get our users the reliability they want from our web app, is to register a new TLD+1 and move our content there, and try to follow any changes to Chrome's heuristics over time.

Comment 16 by a...@scirra.com, Jul 18 2017

I'd also add that in the specific case of hanging, the popup window does not actually need its own process. It could share the parent window's process, providing it got a new main thread.
Cc: haraken@chromium.org
Currently, it's impractical to give it it's own thread: each renderer has one "main" thread, even if it's hosting unrelated origins in the same process.

Making Blink truly multithreaded is a pretty long-shot and not likely to happen any time soon: however, something that might help in the medium term is cooperative scheduling in Blink, which is currently being investigated.
Cc: -junov@chromium.org

Sign in to add a comment