Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Unified Diff: components/password_manager/core/browser/password_manager_unittest.cc

Issue 2607413003: Add security feature to ProvisionalSavePassword (Closed)
Patch Set: Addressed next round of comments. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/password_manager/core/browser/password_manager_unittest.cc
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index f45f191dc78c45ac5e8a20f6a9ae5010fd4f3621..61e0ab0c1a780b3853043aa7ef13b4987414ec56 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -33,6 +33,7 @@ using base::ASCIIToUTF16;
using testing::_;
using testing::AnyNumber;
using testing::Return;
+using testing::ReturnRef;
using testing::SaveArg;
using testing::WithArg;
@@ -67,6 +68,7 @@ class MockPasswordManagerClient : public StubPasswordManagerClient {
void(const autofill::PasswordForm&));
MOCK_METHOD0(AutomaticPasswordSaveIndicator, void());
MOCK_METHOD0(GetPrefs, PrefService*());
+ MOCK_CONST_METHOD0(GetMainFrameURL, const GURL&());
MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
MOCK_CONST_METHOD0(GetStoreResultFilter, const MockStoreResultFilter*());
@@ -135,6 +137,9 @@ class PasswordManagerTest : public testing::Test {
.WillRepeatedly(Return(password_autofill_manager_.get()));
EXPECT_CALL(client_, DidLastPageLoadEncounterSSLErrors())
.WillRepeatedly(Return(false));
+
+ ON_CALL(client_, GetMainFrameURL())
+ .WillByDefault(ReturnRef(GURL::EmptyGURL()));
}
void TearDown() override {
@@ -748,6 +753,104 @@ TEST_F(PasswordManagerTest,
manager()->OnPasswordFormsRendered(&driver_, observed, true);
}
+TEST_F(PasswordManagerTest,
+ ShouldBlockPasswordForSameOriginButDifferentSchemeTest) {
+ PasswordForm form = MakeSimpleForm();
+
+ // Same origin and same scheme.
+ manager()->main_frame_url_ = GURL("https://example.com/login");
+ form.origin = GURL("https://example.com/login");
+ EXPECT_FALSE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+
+ // Same host and same scheme, different port.
+ manager()->main_frame_url_ = GURL("https://example.com:443/login");
+ form.origin = GURL("https://example.com:444/login");
+ EXPECT_FALSE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+
+ // Same host but different scheme (https to http).
+ manager()->main_frame_url_ = GURL("https://example.com/login");
+ form.origin = GURL("http://example.com/login");
+ EXPECT_TRUE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+
+ // Same host but different scheme (http to https).
+ manager()->main_frame_url_ = GURL("https://example.com/login");
+ form.origin = GURL("http://example.com/login");
+ EXPECT_TRUE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+
+ // Different TLD, same schemes.
+ manager()->main_frame_url_ = GURL("https://example.com/login");
+ form.origin = GURL("https://example.org/login");
+ EXPECT_FALSE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+
+ // Different TLD, different schemes.
+ manager()->main_frame_url_ = GURL("https://example.com/login");
+ form.origin = GURL("http://example.org/login");
+ EXPECT_FALSE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+
+ // Different subdomains, same schemes.
+ manager()->main_frame_url_ = GURL("https://sub1.example.com/login");
+ form.origin = GURL("https://sub2.example.org/login");
+ EXPECT_FALSE(
+ manager()->ShouldBlockPasswordForSameOriginButDifferentScheme(form));
+}
+
+// Tests whether two submissions to the same origin but different schemes
+// result in only saving the first submission, which has a secure scheme.
+TEST_F(PasswordManagerTest, AttemptedSavePasswordSameOriginInsecureScheme) {
+ PasswordForm secure_form(MakeSimpleForm());
+ secure_form.origin = GURL("https://example.com/login");
+ secure_form.action = GURL("https://example.com/login");
+ secure_form.signon_realm = secure_form.origin.spec();
+
+ PasswordForm insecure_form(MakeSimpleForm());
+ insecure_form.username_value = ASCIIToUTF16("compromised_user");
+ insecure_form.password_value = ASCIIToUTF16("C0mpr0m1s3d_P4ss");
+ insecure_form.origin = GURL("http://example.com/home");
+ insecure_form.action = GURL("http://example.com/home");
+ insecure_form.signon_realm = insecure_form.origin.spec();
+
+ EXPECT_CALL(*store_, GetLogins(_, _))
+ .WillRepeatedly(WithArg<1>(InvokeEmptyConsumerWithForms()));
+
+ EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage())
+ .WillRepeatedly(Return(true));
+
+ EXPECT_CALL(client_, GetMainFrameURL())
+ .WillRepeatedly(ReturnRef(secure_form.origin));
+
+ // See and submit both forms.
+ std::vector<PasswordForm> observed = {secure_form};
+ manager()->OnPasswordFormsParsed(&driver_, observed);
+ manager()->OnPasswordFormsRendered(&driver_, observed, false);
+ OnPasswordFormSubmitted(secure_form);
+
+ observed = {insecure_form};
+ manager()->OnPasswordFormsParsed(&driver_, observed);
+ manager()->OnPasswordFormsRendered(&driver_, observed, false);
+ OnPasswordFormSubmitted(insecure_form);
+
+ std::unique_ptr<PasswordFormManager> form_manager_to_save;
+ EXPECT_CALL(client_,
+ PromptUserToSaveOrUpdatePasswordPtr(
+ _, CredentialSourceType::CREDENTIAL_SOURCE_PASSWORD_MANAGER))
+ .WillOnce(WithArg<0>(SaveToScopedPtr(&form_manager_to_save)));
+
+ // Navigation after form submit, no forms appear.
+ observed.clear();
+ manager()->OnPasswordFormsParsed(&driver_, observed);
+ manager()->OnPasswordFormsRendered(&driver_, observed, true);
+
+ EXPECT_CALL(*store_, AddLogin(FormMatches(secure_form)));
+ ASSERT_TRUE(form_manager_to_save);
+ form_manager_to_save->Save();
+}
+
// Create a form with both a new and current password element. Let the current
// password value be non-empty and the new password value be empty and submit
// the form. While normally saving the new password is preferred (on change

Powered by Google App Engine
This is Rietveld 408576698