Cross-origin popup window shares main thread of parent
Reported by
a...@scirra.com,
Jun 29 2017
|
||||||||||
Issue descriptionUserAgent: 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.
,
Jun 29 2017
,
Jun 30 2017
,
Jul 3 2017
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.
,
Jul 11 2017
This is not an issue with the CORS protocol. dcheng@, could you please help me assign this to the right person?
,
Jul 12 2017
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.
,
Jul 17 2017
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...
,
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?
,
Jul 17 2017
#8: Try window.open(url, "", "noopener"). There is also some related discussion in issue 732560 .
,
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?
,
Jul 18 2017
Possibly related is issue 738419 in which Chrome seems to confuse the window.opener property with the real window opener.
,
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).
,
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.
,
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 :).
,
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.
,
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.
,
Jul 18 2017
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.
,
Jul 25
|
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by a...@scirra.com
, Jun 29 2017