New issue
Advanced search Search tips

Issue 803193 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jan 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug

Blocking:
issue 802294
issue 807609



Sign in to add a comment

PasswordManager tests executing JS wrongly relies on gesture scope

Project Member Reported by mustaq@chromium.org, Jan 17 2018

Issue description

Tests using ExecuteJavaScriptWithUserGestureForTests
  https://cs.chromium.org/chromium/src/content/browser/frame_host/render_frame_host_impl.cc?rcl=1b24eaae298b9d63adf23431717d8b2a1ba00701&l=749

assume that user activation is available while the function is active, and that the activation expires after this function even if the executed JS script doesn't consume it.

This unrealistic assumption hides other problems in some of these tests.  E.g. PasswordManagerBrowserTestBase::VerifyPasswordIsSavedAndFilled assumes that after executing a JS script, calls to RenderFrameImpl::CommitNavigation() won't to ahead because of lack of user gesture.

Many tests in PasswordManagerBrowserTestBase were failing because of this when we were testing UserActivationV2 (where an activation doesn't expire when the caller goes out of scope).

Not sure how to make the tests more realistic.  I will do a stop-gap fix to make these tests compatible with UserActivationV2.
 

Comment 1 by mustaq@chromium.org, Jan 17 2018

Blocking: 802294

Comment 2 by mustaq@chromium.org, Jan 17 2018

I found the following tests relying this assumption:
PasswordManagerBrowserTestBase.NoFormElementTest
PasswordManagerBrowserTestBase.PromptForFetchSubmit
PasswordManagerBrowserTestBase.PromptForFetchWithNewPasswordsWithoutOnSubmit
PasswordManagerBrowserTestBase.PromptForFetchWithoutOnSubmit
PasswordManagerBrowserTestBase.PromptForXHRSubmit
PasswordManagerBrowserTestBase.PromptForXHRWithNewPasswordsWithoutOnSubmit
PasswordManagerBrowserTestBase.PromptForXHRWithoutOnSubmit

We use ExecuteJavaScriptWithUserGestureForTests to make sure that the script does what we want it to do (like opens a new tab etc). Without user gesture it simply doesn't work. We use ExecuteScriptWithoutUserGesture to verify some expectation on the page and we don't want to produce side effects.
PasswordManagerBrowserTestBase::VerifyPasswordIsSavedAndFilled calls NavigateToFile() twice and expects both to succeed. 

Comment 4 by mustaq@chromium.org, Jan 24 2018

Summary: PasswordManager tests executing JS wrongly relies on gesture scope (was: Browser tests executing JS wrongly relies on gesture scope)
Since the failures here are all related to PasswordManager, it makes sense to focus on only PasswordManager expectations/regressions here.

So far it seems that FormTracker::DidStartProvisionalLoad relies on user gesture scope in a questionable way, and perhaps all 7 failures above are caused by this:
https://cs.chromium.org/chromium/src/components/autofill/content/renderer/form_tracker.cc?rcl=07f8bb44eb43b8dfccdc07d796d5ce0541466d4c&l=159

After a F2F with vasilii@ today, we decided to dig into it.  We first need a minimal HTML where the FireProbablyFormSubmitted() call (in the above link) is correctly executed/avoided.

Comment 5 by mustaq@chromium.org, Jan 24 2018

Seem  Issue 368690  is related?

Comment 6 by mustaq@chromium.org, Jan 24 2018

Two points to aid testing if current code if okay or not:

[A] The source of the questionable assumption in FormTracker::DidStartProvisionalLoad (see the link in #c4) seems to be  Issue 43219 #c31 . It's a hack to snapshot form data (to save for autofill later on) for a site that cancels form submit to handle login through an XHR.

Since the snapshot step seems conditional on not-having-user-gesture, does it mean save-password-prompt won't appear if a page forcibly consumes user activation through a "window.open" call in submitButton.onclick handler?


[B] Here is an old comment re user gestures which I *think* still applies but was wrongly removed because the referred bug had been fixed:
  https://chromium.googlesource.com/chromium/src/+/9db3fef754eaed881babd07fa52ffe366d35a8ac/components/autofill/content/renderer/password_autofill_agent.cc#932
(Note that password_autofill_agent.cc is the original source of the user-gesture-specific task in today's FormTracker.)

Does it mean save-password-prompt won't appear if a site makes a sync-XHR request from within submitButton.onclick handler?

Comment 7 by mustaq@chromium.org, Jan 25 2018

Components: UI>Browser>Autofill
Just confirmed that the hack in FormTracker::DidStartProvisionalLoad (see above) has an unintended outcome.

After filling a login form, if the user clicks on a link to go somewhere (instead of form submission), Chrome shouldn't show the prompt to save password.  We have the test PasswordManagerBrowserTestBase, NoPromptIfLinkClicked for this expectation:
https://cs.chromium.org/chromium/src/chrome/browser/password_manager/password_manager_browsertest.cc?rcl=1fd722308b8c3d4533b19ad2df5d40752e945e01&l=925

However, if the "click" handler for the link consumes user activation, the save password prompt is shown!  To repro, prepend the following line in the script in the above test, and the test fails:
  "document.getElementById('link').addEventListener('click', function() { window.open(''); });"

[Console output]
../../chrome/browser/password_manager/password_manager_browsertest.cc:940: Failure
Value of: prompt_observer->IsSavePromptShownAutomatically()
  Actual: true
Expected: false

I launched 'python -m SimpleHTTPServer' and tested on the Chrome test files (e.g. http://localhost:8000/chrome/test/data/password/password_fetch_submit.html)

I can confirm that with UserActivationV2 on the prompt doesn't appear due to the sticky user gesture. Thus, the behavior is indeed broken.

Re [A]: I'd not call it unintended. Just calling FormTracker::DidStartProvisionalLoad isn't enough for the prompt to appear. The form should disappear. What Chrome sees:
- there is a click on a link (the form was filled).
- some JS kicked-in and did something looking like logging the user in.
- user landed on a page without form -> showing the prompt is reasonable.

Re [B]: Yes. But it's not that bad, if another navigation is following (like the server checked the credentials and caused a navigation) then it appears.
Example 1: edit 'password_fetch_submit.html' and change
<form onsubmit="send_fetch(); window.top.location.href = 'done.html'; return false;" id="testform"> 
The prompt appears.
Example 2: change the line as above and remove the body of  "function(response) {}". The prompt doesn't appear.


We think that it's better to show the prompt even if it's a mistake than not to show it when it should appear. Still clicking on a link and navigating somewhere (while there is a form prefilled with some trash somewhere on the page) is a common case that we'd like to address. Do you know a way how we can easily detected navigations from clicking a link?

Comment 9 by mustaq@chromium.org, Jan 25 2018

For the last few hours, I have been trying to isolate click navigation without relying user activation.  I think there's a way, but other references to FrameLoader::Load() made it a bit tricky.

Project Member

Comment 10 by bugdroid1@chromium.org, Jan 30 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/9a7a3991e35998df423168d6f550974d41944f72

commit 9a7a3991e35998df423168d6f550974d41944f72
Author: Mustaq Ahmed <mustaq@google.com>
Date: Tue Jan 30 20:10:22 2018

Remove user activation check for autofill provisional save.

The check is needed to avoid password prompt when a user clicks
a link instead of submitting a filled form.  The original condition
was a weak signal to detect click-on-link, and fails with
UserActivationV2 which changes the scope of a user activation.

For records, only one test relied on the original activation check
is PasswordManagerBrowserTestBase.NoPromptIfLinkClicked .

Bug:  803193 ,  772432 
Change-Id: I33545d9550f7bd125ff8eb739c998ee1f1a48c52
Reviewed-on: https://chromium-review.googlesource.com/884368
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Vasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: Roger McFarlane <rogerm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533004}
[modify] https://crrev.com/9a7a3991e35998df423168d6f550974d41944f72/components/autofill/content/renderer/form_tracker.cc

Status: Fixed (was: Assigned)
Blocking: 807609

Sign in to add a comment