Link navigation cancellation with beforeunload and replaceState
Reported by
tom...@gmail.com,
Mar 26 2018
|
|||||||||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.45 Safari/537.36 Example URL: https://zeroid.qc.to/temp/chrome_onbeforeunload/ Steps to reproduce the problem: 1. Load the page 2. Click on "Go to http://httpbin.org/" What is the expected behavior? The page should navigate to http://httpbin.org What went wrong? http://httpbin.org in (canceled) status in DevTool Network tab. Does it occur on multiple sites: Yes Is it a problem with a plugin? No Did this work before? Yes 65.0.3325.181 Does this work in other browsers? Yes Chrome version: 66.0.3359.45 Channel: beta OS Version: 10.0 Flash Version: Only happens if the inner frame send a postMessage to the outer frame and the outer frame executes the "replaceState" command. The navigation occurs correctly if the replaceState involved by the inner frame.html, but it's not possible in some cases (eg. sandboxed iframe) My usecase: I want to save the scroll position of a sandboxed iframe to history.state before the navigation. (to be able to restore it when the user presses the back button)
,
Mar 26 2018
Unable to reproduce the issue on chrome reported version 66.0.3359.45 using Windows-10 with steps mentioned below: 1) Launched chrome reported version and navigated to URL: https://zeroid.qc.to/temp/chrome_onbeforeunload/ 2) Clicked on "Go to http://httpbin.org/", page navigated to httpbin.org and didn't observed any cancel status in DevTools Network tab Observations: Also tested this by dragging and dropping the file attached in comment#0, didn't observed any cancel status in Devtools. @Reporter: Please find the attached screen cast for your reference and let us know if we missed anything in reproducing the issue, try to test this issue by creating new person with no apps and extensions in it and let us know if the issue still persists. Thanks!
,
Mar 26 2018
Thanks for the response, hitting "Reset all to default" on chrome://flags/ did fixed the issue.
,
Mar 26 2018
Thank you for providing more feedback. Adding the requester to the cc list. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Mar 26 2018
Closing as per comment #3.
,
May 31 2018
I'm having this issue again in both stable and beta channel even after pressing "Reset all to default" on page chrome://flags/ Attachhing video + files required for reproduce in case of the url (https://zeroid.qc.to/temp/chrome_onbeforeunload/) not working.
,
May 31 2018
Thanks. I wonder if this is related to site isolation. Could you try setting chrome://flags#site-isolation-trial-opt-out to "Opt-Out", does the issue go away? (more details: https://www.chromium.org/Home/chromium-security/site-isolation#TOC-Diagnosing-Issues)
,
May 31 2018
Yes, setting "Opt-Out" for "Site isolation trial opt-out" does solves the problem. Also: Links that points to same-origin not affected by this issue.
,
May 31 2018
Thanks, over to site isolation team
,
May 31 2018
Thanks for the report! It's unfortunate this didn't get at least a Navigation label earlier, since we might have been able to track it down. Is the repro URL down? I'm getting a connection refused error on https://zeroid.qc.to/temp/chrome_onbeforeunload/.
,
May 31 2018
Using the repro files attached to the original report, I can confirm the bug is Site Isolation specific on Windows and Mac Stable 67.0.3396.62, Windows Canary 69.0.3446.0, and on a Linux trunk build. We'll look into it!
,
May 31 2018
Worth noting that the iframe itself is not cross-site, so it's not an out-of-process iframe. Instead, I suspect this is about the replaceState canceling an ongoing cross-process navigation. Site Isolation being enabled changes the cross-site httpbin.org link click from same-process to cross-process. This may be something related to PlzNavigate and cross-process navigations.
,
May 31 2018
Nasko found this is due to the following code in RenderFrameHostManager::CommitPendingIfNecessary:
// A navigation in the original page has taken place. Cancel the speculative
// one. Only do it for user gesture originated navigations to prevent page
// doing any shenanigans to prevent user from navigating. See
// https://code.google.com/p/chromium/issues/detail?id=75195
if (was_caused_by_user_gesture) {
frame_tree_node_->ResetNavigationRequest(false, true);
CleanUpNavigation();
}
Related to issue 75195 , where pages used to be able to prevent the user from leaving using replaceState.
,
May 31 2018
Alex is picking this up. It looks like the problem is that the replaceState in this case has a user gesture, so Chrome is treating it like the case where a user starts a slow cross-process navigation, then later decides to click a same-site link instead. We shouldn't be canceling the cross-process navigation for same-document navigations, though, just cross-document ones that have user gestures.
,
May 31 2018
Another issue I see is that we're also committing pending sandbox flags and feature policy from same-document commits:
void RenderFrameHostManager::DidNavigateFrame(
RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture) {
CommitPendingIfNecessary(render_frame_host, was_caused_by_user_gesture);
// Make sure any dynamic changes to this frame's sandbox flags and feature
// policy that were made prior to navigation take effect.
CommitPendingFramePolicy();
}
I'm pretty sure that we shouldn't be doing that, +iclelland as FYI and to confirm. This would mean that a same-document commit would send pending frame policy to proxies, and if a proxy were to later add a subframe, it'd end up with incorrect sandbox flags or feature policy.
We don't see a good reason for calling CommitPendingIfNecessary() for same-document commits, so I'm leaning toward not calling either of these two functions and just returning early for same-document cases in DidNavigateFrame().
,
May 31 2018
Also, we might have another problem here with user gesture. The reason that the replaceState ends up with user gesture is really obscure: apparently, we keep the user gesture bit that we send in DidCommit params on RenderViewImpl::navigation_gesture_ (!), set it in RenderFrameImpl::DidStartProvisionalLoad, and then clear it as part of DidCommit in RenderFrameImpl::MakeDidCommitProvisionalLoadParams. Except that if the DidCommit happens in another process, we'll never clear it and leave it there for the next navigation in that process! In this case, the navigation to httpbin.org stores the gesture on RenderView as part of its DidStart, and then the subsequent replaceState grabs it. Although this probably only affects same-document navigations (which will do DidCommit without DidStart), the fact that a navigation can grab the user gesture from a prior navigation seems wrong, and we should try to clean this up as well. I'll open a separate bug.
,
May 31 2018
Opened issue 848487 for the user gesture problem in #16.
,
Jun 4 2018
Re: #15 -- Totally agree, we should not be committing the pending policy on a same-document navigation.
,
Jun 4 2018
#18: Thanks. I split off the issue with pending frame policy and same-document navigations into issue 849311 , so it's easier to track the merges.
,
Jun 4 2018
Also, I've got a draft CL to fix the main issue here at https://chromium-review.googlesource.com/c/chromium/src/+/1081937.
,
Jun 4 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/a5f402352c05e6a505025598af8421dd9dfa7236 commit a5f402352c05e6a505025598af8421dd9dfa7236 Author: Alex Moshchuk <alexmos@chromium.org> Date: Mon Jun 04 19:25:53 2018 Do not let a same-document commit cancel ongoing cross-process navigations. When a cross-process navigation is started but is slow to commit, a later navigation on the original page should normally cancel it, when performed with a user gesture - see issue 75195 . However, issue 825677 shows that same-document navigations should not cancel a cross-process navigation, even if they have a user gesture. This CL modifies the cancellation logic to never apply for same-document navigations. Bug: 825677 Change-Id: I8bd20086c66997b48ac83b0500530be6b16a40cd Reviewed-on: https://chromium-review.googlesource.com/1081937 Commit-Queue: Alex Moshchuk <alexmos@chromium.org> Reviewed-by: Charlie Reis <creis@chromium.org> Cr-Commit-Position: refs/heads/master@{#564183} [modify] https://crrev.com/a5f402352c05e6a505025598af8421dd9dfa7236/content/browser/frame_host/navigator_impl.cc [modify] https://crrev.com/a5f402352c05e6a505025598af8421dd9dfa7236/content/browser/frame_host/render_frame_host_manager.cc [modify] https://crrev.com/a5f402352c05e6a505025598af8421dd9dfa7236/content/browser/frame_host/render_frame_host_manager.h [modify] https://crrev.com/a5f402352c05e6a505025598af8421dd9dfa7236/content/browser/frame_host/render_frame_host_manager_unittest.cc [modify] https://crrev.com/a5f402352c05e6a505025598af8421dd9dfa7236/content/browser/site_per_process_browsertest.cc
,
Jun 5 2018
I'ver just verified the fix in #21 in Mac Canary 69.0.3450.0 using the repro attached to the original report. Requesting merge to M68 - the fix should be safe as it's adding a check for a same-document case in a well-contained place, and the rest is just plumbing to get that info to the right function.
,
Jun 6 2018
Your change meets the bar and is auto-approved for M68. Please go ahead and merge the CL to branch 3440 manually. Please contact milestone owner if you have questions. Owners: cmasso@(Android), kariahda@(iOS), bhthompson@(ChromeOS), abdulsyed@(Desktop) For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Jun 6 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/eaa7616709fbf2e419928f5ea69fd70890d2bedc commit eaa7616709fbf2e419928f5ea69fd70890d2bedc Author: Alex Moshchuk <alexmos@chromium.org> Date: Wed Jun 06 21:08:45 2018 Do not let a same-document commit cancel ongoing cross-process navigations (Merge to M68) When a cross-process navigation is started but is slow to commit, a later navigation on the original page should normally cancel it, when performed with a user gesture - see issue 75195 . However, issue 825677 shows that same-document navigations should not cancel a cross-process navigation, even if they have a user gesture. This CL modifies the cancellation logic to never apply for same-document navigations. TBR=alexmos@chromium.org (cherry picked from commit a5f402352c05e6a505025598af8421dd9dfa7236) Bug: 825677 Change-Id: I8bd20086c66997b48ac83b0500530be6b16a40cd Reviewed-on: https://chromium-review.googlesource.com/1081937 Commit-Queue: Alex Moshchuk <alexmos@chromium.org> Reviewed-by: Charlie Reis <creis@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#564183} Reviewed-on: https://chromium-review.googlesource.com/1089728 Reviewed-by: Alex Moshchuk <alexmos@chromium.org> Cr-Commit-Position: refs/branch-heads/3440@{#220} Cr-Branched-From: 010ddcfda246975d194964ccf20038ebbdec6084-refs/heads/master@{#561733} [modify] https://crrev.com/eaa7616709fbf2e419928f5ea69fd70890d2bedc/content/browser/frame_host/navigator_impl.cc [modify] https://crrev.com/eaa7616709fbf2e419928f5ea69fd70890d2bedc/content/browser/frame_host/render_frame_host_manager.cc [modify] https://crrev.com/eaa7616709fbf2e419928f5ea69fd70890d2bedc/content/browser/frame_host/render_frame_host_manager.h [modify] https://crrev.com/eaa7616709fbf2e419928f5ea69fd70890d2bedc/content/browser/frame_host/render_frame_host_manager_unittest.cc [modify] https://crrev.com/eaa7616709fbf2e419928f5ea69fd70890d2bedc/content/browser/site_per_process_browsertest.cc
,
Jun 6 2018
Thanks Alex! Since you filed issue 848487 and issue 849311 for the followup tasks, I think this one can be marked fixed. The fix will be available in M68, giving it a bit of time to bake to be safe.
,
Jun 7 2018
Able to reproduce this issue on build without fix(tested on 68.0.3440.14) by enabling site-per-process flag. Hence verifying the issue on 68.0.3440.17. Now not observing any error message in network tab. Navigated to https://zeroid.qc.to/temp/chrome_onbeforeunload/ and opened devtools, clicked on http://httpbin.org/ and able to navigate successfully. Attaching screencast for reference. As fix is working as expected, adding Verified labels. Thanks!
,
Jun 8 2018
Just a note that there's one more followup issue regarding origin updates for same-document navigations, for which I've just filed issue 850999. |
|||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||
Comment 1 by susan.boorgula@chromium.org
, Mar 26 2018