Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use appropriate site instance for cross-site nav's #15821

Merged
merged 19 commits into from Dec 5, 2018
Merged

fix: use appropriate site instance for cross-site nav's #15821

merged 19 commits into from Dec 5, 2018

Conversation

ppontes
Copy link
Member

@ppontes ppontes commented Nov 23, 2018

Description of Change

When a window is opened with window.open to navigate to a cross-site destination, the new site instance should belong to the browsing instance of the opener window in order not to break scripting relationships between windows.

fixes #8100.

This change turns Chromium's site isolation on and depends on it being on in order to work properly. Turning on site isolation revealed the following latent problems that are / will be fixed also in this PR:

  • If a cross-site redirection happens during a navigation, the renderer process that will handle the final URL will be locked to the pre-redirection URL with Chromium's child process security. If the page tries to access local resources, Chromium will refuse and kill the renderer process.
  • Chromium now kills renderer processes that attempt to access resources for which they have no permissions. This means that the "custom non standard schemes cannot access localStorage" UT had to be adapted.

The fix also requires the following to be addressed:

  • If a cross-site redirection happens during a navigation, Chromium discards the speculative RFH that was created for the pre-redirection URL. This is harmless in Chromium but Electron reacts by asynchronously closing the associated BrowserWindow. User sees the new window navigating to the final URL and then being closed.

Checklist

Release Notes

Notes: Fixed a bug where window.opener of a window created with window.open from a sandboxed renderer was null.

@ppontes ppontes requested a review from a team November 23, 2018 23:47
@ppontes ppontes removed the wip ⚒ label Nov 30, 2018
@ppontes ppontes changed the title [WIP] fix: use appropriate site instance for cross-site nav's fix: use appropriate site instance for cross-site nav's Nov 30, 2018
@ppontes ppontes added wip ⚒ and removed wip ⚒ labels Nov 30, 2018
render_view_host->GetProcess()->GetID() ==
currently_committed_process_id) {
currently_committed_process_id = -1;
Emit("current-render-view-deleted",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better name for this event?

Copy link
Member

@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with some minor style changes.

@@ -781,8 +781,23 @@ void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
impl->disable_hidden_ = !background_throttling_;
}

void WebContents::RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) {
currently_committed_process_id = new_host->GetProcess()->GetID();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

member variables should end with trailing _

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, fixed.

content::RenderViewHost* new_host) {
currently_committed_process_id = new_host->GetProcess()->GetID();
}

void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
Emit("render-view-deleted", render_view_host->GetProcess()->GetID());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little comment stating that this event is necessary for tracking any states with respect to intermediate render view hosts aka speculative render view hosts. Currently used by object-registry.js to ref count remote objects.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, added.

content::SiteInstance* speculative_instance,
const GURL& dest_url,
bool has_response_started) const {
bool navigationWasRedirected = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variable should be snake case, navigation_was_redirected

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, fixed.

@deepak1556
Copy link
Member

@ppontes can you rebase on latest master, it should be good to go. Thanks!

Copy link
Member

@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@zcbenz zcbenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't find any problem, this is awesome.

@zcbenz
Copy link
Member

zcbenz commented Dec 5, 2018

Failing tests are the usual flaky ones, I'm merging with them ignored.

@zcbenz zcbenz merged commit d5d1fa8 into electron:master Dec 5, 2018
@release-clerk
Copy link

release-clerk bot commented Dec 5, 2018

Release Notes Persisted

Fixed a bug where window.opener of a window created with window.open from a sandboxed renderer was null.

@ppontes
Copy link
Member Author

ppontes commented Dec 5, 2018

/trop run backport

@MarshallOfSound
Copy link
Member

@ppontes You need to be on an approved user list to run trop commands.

4.x is nearing the end of its beta cycle, the previous iteration of this change broke the release. How confident are we this won't destabilize 4.0?

@ppontes
Copy link
Member Author

ppontes commented Dec 5, 2018

@MarshallOfSound Thanks for the warning, I suspected that but since the trop docs are outdated I still gave it a try.
I'm reasonably confident as we solved the issues found meanwhile and added UT's to verify them. Of course there's always some risk associated with turning on site isolation. Adding @deepak1556 for input.

@deepak1556
Copy link
Member

@MarshallOfSound I would like to see this backported to 4.x line, and get an early feedback on using site isolation. There is only so much we can test here wrt navigations. Also this PR fixes some really troublesome usages of site instances. The only reason the last PR got reverted was because it compromised a common navigation code path.

@MarshallOfSound
Copy link
Member

Thanks @ppontes and @deepak1556

I'm tentatively going to land this ready for the next 4.x release but cc'ing @sofianguy to give a heads up to the AFP folks that this change is landing. Basically any weird navigation or window.open behavior in the next 4.x release is probably coming from this PR, although we don't expect anything bad to happen and we've tested the common paths as well as we can without sending it through apps.

We can always revert before the next 4.x release if someone finds something.

@MarshallOfSound
Copy link
Member

/trop run backport

@trop
Copy link
Contributor

trop bot commented Dec 5, 2018

The backport process for this PR has been manually initiated, here we go! :D

@trop
Copy link
Contributor

trop bot commented Dec 5, 2018

I was unable to backport this PR to "4-0-x" cleanly;
you will need to perform this backport manually.

@MarshallOfSound
Copy link
Member

cc @ppontes looks like the patch doesn't apply cleanly, can you take care of the manual backport?

@ppontes
Copy link
Member Author

ppontes commented Dec 5, 2018

@MarshallOfSound yep, will do. Thanks.

@ckerr
Copy link
Member

ckerr commented Dec 6, 2018

@ppontes, do you have an estimate on when you can do this?

I'm wondering if we should try to get this into a beta release later this week so that there will more public testing time leading up to 4.0.0

@ppontes
Copy link
Member Author

ppontes commented Dec 6, 2018

@ckerr sorry for the delay, got some surprising UT failures as a setting failed to reach brightray in 4-0-x, as brightray is gone from master. Everything's fine now and the PR is ready: #15969

@ppontes ppontes deleted the ppontes/8100-use-proper-site-instance-candidate branch December 20, 2018 13:05
@dataich
Copy link
Contributor

dataich commented Feb 4, 2019

Do you have plan to release this fix on 4.x?

@ppontes
Copy link
Member Author

ppontes commented Feb 5, 2019

@dataich , this is a considerable change that got ready just as 4.x was about to be released, so unfortunately we decided not to include it in 4.x after all. It is available from 5.x.

@dataich
Copy link
Contributor

dataich commented Feb 5, 2019

@ppontes thanks for your reply. I wait stable 5.x release😢

@@ -1470,29 +1472,6 @@ describe('BrowserWindow module', () => {

const preload = path.join(fixtures, 'module', 'preload-sandbox.js')

// http protocol to simulate accessing another domain. This is required
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ppontes is there any reason why you removed the usage of interceptStringProtocol? I'm considering using this again for #18173

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I don't remember the reason. Feel free to try to use it again according to your needs.

}
embedder.once('render-view-deleted', closedByEmbedder)
embedder.once('current-render-view-deleted', closedByEmbedder)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that "RenderViewDeleted" implies that the window should be closed?

Our Electron app is failing to use Google Sign-in, with a similar behavior to what is described here, and I've traced the issue to the current-render-view-deleted event being emitted before the sign-in is ready causing it to close prematurely.

For our app, the current-render-view-deleted event is only emitted in this situation, so it was safe to simply comment this line. Do you know what are the general implications of removing this handler?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you understand what causes RenderViewDeleted to be fired in the first place?

@deepak1556 can confirm / correct me, I believe we need to depend on this event to cleanup our BrowserWindow stuff when we assume that something other than the user is triggering the window to close. So it'd be useful to understand why something's triggering the RenderView to be deleted while Google Sign-in still depends on the popup window being open.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW @tarruda, Google is shutting down sign-in in non-browsers: https://security.googleblog.com/2019/04/better-protection-against-man-in-middle.html

It's quite possible there's a separate issue here, but for Google sign-in specifically, you should probably see if you can switch to the OAuth flow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you understand what causes RenderViewDeleted to be fired in the first place?

Not certain, but it seemed to happen when the Google SSO window navigated to another URL (where it normally shows "please wait..." before closing the window).

Also, this didn't always happen: When I tried to sign in by opening our app login window directly with a BrowserWindow, the issue was not reproducible. It only happened during normal app usage, when the login window was opened with window.open.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW @tarruda, Google is shutting down sign-in in non-browsers: https://security.googleblog.com/2019/04/better-protection-against-man-in-middle.html

It's quite possible there's a separate issue here, but for Google sign-in specifically, you should probably see if you can switch to the OAuth flow.

@nornagon I'm not familiar with the details of how theh Google sign-in works, but I assume we already use the OAuth flow since that announcement is already one year old and everything was working fine for the past couple of months.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily; Google has been rolling it out on a percentage basis per-account since a few months ago. OAuth flow means you do sign-in in the browser and get a token back in your app.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily; Google has been rolling it out on a percentage basis per-account since a few months ago. OAuth flow means you do sign-in in the browser and get a token back in your app.

Hmm now I remember having to change user-agent in order for Google Sign-in to work, that must have been the reason :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that seems to work for some people for now, but Google is pretty committed to preventing people from doing what you're doing, so I wouldn't be at all surprised if they break it in other, more difficult-to-work-around ways without warning in the future.

@bughit
Copy link
Contributor

bughit commented Apr 1, 2022

This change turns Chromium's site isolation on and depends on it being on in order to work properly.

Could someone please clarify whether the above means that disabling site isolation via --disable-site-isolation-trials is unsupported?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

In sandbox mode, window.opener doesn't work when children are from different domain
10 participants