Chromium Code Reviews| Index: chrome/browser/password_manager/password_manager_browsertest.cc |
| diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc |
| index a17d1f5b00776ca754c6640f3e636d550018bcfb..de4ebe119479efbbd454d300c04c5b97fee593ab 100644 |
| --- a/chrome/browser/password_manager/password_manager_browsertest.cc |
| +++ b/chrome/browser/password_manager/password_manager_browsertest.cc |
| @@ -1412,6 +1412,80 @@ IN_PROC_BROWSER_TEST_F( |
| EXPECT_FALSE(prompt_observer->IsShowingSavePrompt()); |
| } |
| +// Tests whether a attempted submission of a malicious credentials gets blocked. |
| +// This simulates a case which is described in http://crbug.com/571580. |
| +IN_PROC_BROWSER_TEST_F( |
| + PasswordManagerBrowserTestBase, |
| + NoPromptForSeperateLoginFormWhenSwitchingFromHttpsToHttp) { |
| + base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| + ::switches::kAllowRunningInsecureContent); |
| + base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| + ::switches::kIgnoreCertificateErrors); |
| + const base::FilePath::CharType kDocRoot[] = |
| + FILE_PATH_LITERAL("chrome/test/data"); |
| + net::EmbeddedTestServer https_test_server( |
| + net::EmbeddedTestServer::TYPE_HTTPS); |
| + https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot)); |
| + ASSERT_TRUE(https_test_server.Start()); |
| + |
| + std::string path = "/password/password_form.html"; |
| + GURL https_url(https_test_server.GetURL(path)); |
| + ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme)); |
| + |
| + NavigationObserver form_observer(WebContents()); |
| + ui_test_utils::NavigateToURL(browser(), https_url); |
| + form_observer.Wait(); |
| + |
| + std::string fill_and_submit_redirect = |
| + "document.getElementById('username_redirect').value = 'user';" |
| + "document.getElementById('password_redirect').value = 'password';" |
| + "document.getElementById('submit_redirect').click()"; |
| + ASSERT_TRUE( |
| + content::ExecuteScript(RenderViewHost(), fill_and_submit_redirect)); |
| + |
| + NavigationObserver redirect_observer(WebContents()); |
| + redirect_observer.SetPathToWaitFor("/password/redirect.html"); |
| + redirect_observer.Wait(); |
| + |
| + // Normally the redirect happens to done.html. Here an attack is simulated |
| + // that hijacks the redirect to a attacker controlled page. |
| + GURL http_url( |
| + embedded_test_server()->GetURL("/password/simple_password.html")); |
| + std::string attacker_redirect = |
| + "window.location.href = '" + http_url.spec() + "';"; |
| + ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), attacker_redirect)); |
| + |
| + NavigationObserver attacker_observer(WebContents()); |
| + attacker_observer.SetPathToWaitFor("/password/simple_password.html"); |
| + attacker_observer.Wait(); |
| + |
| + std::string fill_and_submit_attacker_form = |
| + "document.getElementById('username_field').value = 'attacker_username';" |
| + "document.getElementById('password_field').value = 'attacker_password';" |
| + "document.getElementById('input_submit_button').click()"; |
| + ASSERT_TRUE( |
| + content::ExecuteScript(RenderViewHost(), fill_and_submit_attacker_form)); |
| + |
| + NavigationObserver done_observer(WebContents()); |
| + done_observer.SetPathToWaitFor("/password/done.html"); |
| + done_observer.Wait(); |
| + |
|
vasilii
2017/01/12 14:59:21
We need WaitForPasswordStore() to be safe here.
jdoerrie
2017/01/12 17:40:58
Done.
|
| + BubbleObserver prompt_observer(WebContents()); |
| + EXPECT_TRUE(prompt_observer.IsShowingSavePrompt()); |
| + prompt_observer.AcceptSavePrompt(); |
| + |
| + // Wait for password store and check that credentials are stored. |
| + WaitForPasswordStore(); |
| + scoped_refptr<password_manager::TestPasswordStore> password_store = |
| + static_cast<password_manager::TestPasswordStore*>( |
| + PasswordStoreFactory::GetForProfile( |
| + browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS) |
| + .get()); |
| + EXPECT_FALSE(password_store->IsEmpty()); |
|
vasilii
2017/01/12 14:59:21
Is it needed?
jdoerrie
2017/01/12 17:40:58
No, it's implied by a successful execution of |Che
|
| + CheckThatCredentialsStored(password_store.get(), base::ASCIIToUTF16("user"), |
| + base::ASCIIToUTF16("password")); |
| +} |
| + |
| IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, |
| PromptWhenPasswordFormWithoutUsernameFieldSubmitted) { |
| scoped_refptr<password_manager::TestPasswordStore> password_store = |