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

Side by Side Diff: components/safe_browsing/password_protection/password_protection_service_unittest.cc

Issue 2747313002: PasswordProtectionService verdict cache management (Closed)
Patch Set: comments addressed partially Created 3 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 #include "components/safe_browsing/password_protection/password_protection_servi ce.h" 4 #include "components/safe_browsing/password_protection/password_protection_servi ce.h"
5 5
6 #include "base/memory/ptr_util.h" 6 #include "base/memory/ptr_util.h"
7 #include "base/run_loop.h" 7 #include "base/run_loop.h"
8 #include "base/strings/string_number_conversions.h"
8 #include "base/test/histogram_tester.h" 9 #include "base/test/histogram_tester.h"
9 #include "components/safe_browsing_db/test_database_manager.h" 10 #include "components/safe_browsing_db/test_database_manager.h"
11 #include "components/sync_preferences/testing_pref_service_syncable.h"
10 #include "content/public/test/test_browser_thread_bundle.h" 12 #include "content/public/test/test_browser_thread_bundle.h"
11 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
13 15
14 namespace { 16 namespace {
15 17
16 const char kPasswordReuseMatchWhitelistHistogramName[] = 18 const char kPasswordReuseMatchWhitelistHistogramName[] =
17 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist"; 19 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist";
18 const char kWhitelistedUrl[] = "http://inwhitelist.com"; 20 const char kWhitelistedUrl[] = "http://inwhitelist.com";
19 const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com"; 21 const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com";
(...skipping 12 matching lines...) Expand all
32 ~MockSafeBrowsingDatabaseManager() override {} 34 ~MockSafeBrowsingDatabaseManager() override {}
33 35
34 private: 36 private:
35 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager); 37 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
36 }; 38 };
37 39
38 class PasswordProtectionServiceTest : public testing::Test { 40 class PasswordProtectionServiceTest : public testing::Test {
39 public: 41 public:
40 PasswordProtectionServiceTest(){}; 42 PasswordProtectionServiceTest(){};
41 43
44 ~PasswordProtectionServiceTest() override {
45 content_setting_map_->ShutdownOnUIThread();
46 }
47
48 LoginReputationClientResponse CreateVerdictProto(
49 LoginReputationClientResponse::VerdictType verdict,
50 int cache_duration_sec,
51 const std::string& cache_expression) {
52 LoginReputationClientResponse verdict_proto;
53 verdict_proto.set_verdict_type(verdict);
54 verdict_proto.set_cache_duration_sec(cache_duration_sec);
55 verdict_proto.set_cache_expression(cache_expression);
56 return verdict_proto;
57 }
58
42 void SetUp() override { 59 void SetUp() override {
43 database_manager_ = new MockSafeBrowsingDatabaseManager(); 60 database_manager_ = new MockSafeBrowsingDatabaseManager();
44 password_protection_service_ = 61 password_protection_service_ =
45 base::MakeUnique<PasswordProtectionService>(database_manager_); 62 base::MakeUnique<PasswordProtectionService>(database_manager_);
63 HostContentSettingsMap::RegisterProfilePrefs(test_pref_service_.registry());
64 content_setting_map_ = new HostContentSettingsMap(
65 &test_pref_service_, false /* incognito */, false /* guest_profile */);
66 }
67
68 bool UrlMatchCacheExpression(const GURL& url,
69 const std::string& cache_expression) {
70 std::vector<std::string> hosts;
71 std::vector<std::string> paths;
72 V4ProtocolManagerUtil::GenerateHostAndPathVariants(url, &hosts, &paths);
73 return PasswordProtectionService::HostPathVariantsMatchCacheExpression(
74 hosts, paths, cache_expression);
46 } 75 }
47 76
48 protected: 77 protected:
49 // |thread_bundle_| is needed here because this test involves both UI and IO 78 // |thread_bundle_| is needed here because this test involves both UI and IO
50 // threads. 79 // threads.
51 content::TestBrowserThreadBundle thread_bundle_; 80 content::TestBrowserThreadBundle thread_bundle_;
52 scoped_refptr<MockSafeBrowsingDatabaseManager> database_manager_; 81 scoped_refptr<MockSafeBrowsingDatabaseManager> database_manager_;
53 std::unique_ptr<PasswordProtectionService> password_protection_service_; 82 std::unique_ptr<PasswordProtectionService> password_protection_service_;
83 sync_preferences::TestingPrefServiceSyncable test_pref_service_;
84 scoped_refptr<HostContentSettingsMap> content_setting_map_;
54 }; 85 };
55 86
56 TEST_F(PasswordProtectionServiceTest, 87 TEST_F(PasswordProtectionServiceTest,
57 TestPasswordReuseMatchWhitelistHistogram) { 88 TestPasswordReuseMatchWhitelistHistogram) {
58 const GURL whitelisted_url(kWhitelistedUrl); 89 const GURL whitelisted_url(kWhitelistedUrl);
59 const GURL not_whitelisted_url(kNoneWhitelistedUrl); 90 const GURL not_whitelisted_url(kNoneWhitelistedUrl);
60 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(whitelisted_url)) 91 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(whitelisted_url))
61 .WillOnce(testing::Return(true)); 92 .WillOnce(testing::Return(true));
62 EXPECT_CALL(*database_manager_.get(), 93 EXPECT_CALL(*database_manager_.get(),
63 MatchCsdWhitelistUrl(not_whitelisted_url)) 94 MatchCsdWhitelistUrl(not_whitelisted_url))
(...skipping 14 matching lines...) Expand all
78 testing::ElementsAre(base::Bucket(1, 1))); 109 testing::ElementsAre(base::Bucket(1, 1)));
79 110
80 // Non-whitelisted url should increase "False" bucket by 1. 111 // Non-whitelisted url should increase "False" bucket by 1.
81 password_protection_service_->RecordPasswordReuse(not_whitelisted_url); 112 password_protection_service_->RecordPasswordReuse(not_whitelisted_url);
82 base::RunLoop().RunUntilIdle(); 113 base::RunLoop().RunUntilIdle();
83 EXPECT_THAT( 114 EXPECT_THAT(
84 histograms.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName), 115 histograms.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName),
85 testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1))); 116 testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1)));
86 } 117 }
87 118
119 TEST_F(PasswordProtectionServiceTest, TestParseVerdictEntry) {
120 int now_in_sec = static_cast<int>(base::Time::Now().ToDoubleT());
121 std::unique_ptr<base::DictionaryValue> valid_verdict_entry =
122 base::MakeUnique<base::DictionaryValue>();
123 valid_verdict_entry->SetInteger("cache_ttl", 10 * 60);
124 valid_verdict_entry->SetInteger("cache_creation_time", now_in_sec);
125 valid_verdict_entry->SetInteger("verdict", 1 /* SAFE */);
126
127 std::unique_ptr<base::DictionaryValue> invalid_verdict_entry =
128 base::MakeUnique<base::DictionaryValue>();
129 invalid_verdict_entry->SetString("cache_ttl", "invalid_ttl");
130
131 int cache_creation_time, cache_ttl, verdict_type_value;
132 // ParseVerdictEntry fails if input is empty.
133 EXPECT_FALSE(PasswordProtectionService::ParseVerdictEntry(
134 nullptr, &cache_creation_time, &cache_ttl, &verdict_type_value));
135
136 // ParseVerdictEntry fails if the input dict value is invalid.
137 EXPECT_FALSE(PasswordProtectionService::ParseVerdictEntry(
138 invalid_verdict_entry.get(), &cache_creation_time, &cache_ttl,
139 &verdict_type_value));
140
141 // ParseVerdictEntry success case.
142 ASSERT_TRUE(PasswordProtectionService::ParseVerdictEntry(
143 valid_verdict_entry.get(), &cache_creation_time, &cache_ttl,
144 &verdict_type_value));
145 EXPECT_EQ(600, cache_ttl);
146 EXPECT_EQ(now_in_sec, cache_creation_time);
147 EXPECT_EQ(LoginReputationClientResponse::SAFE,
148 static_cast<LoginReputationClientResponse::VerdictType>(
149 verdict_type_value));
150 }
151
152 TEST_F(PasswordProtectionServiceTest, TestUrlMatchCacheExpression) {
153 // Cache expression without path.
154 std::string cache_expression("google.com");
155 EXPECT_TRUE(UrlMatchCacheExpression(GURL("https://www.google.com"),
156 cache_expression));
157 EXPECT_TRUE(
158 UrlMatchCacheExpression(GURL("http://google.com"), cache_expression));
159 EXPECT_TRUE(UrlMatchCacheExpression(GURL("https://maps.google.com"),
160 cache_expression));
161 EXPECT_TRUE(UrlMatchCacheExpression(
162 GURL("https://www.google.com/maps/local/"), cache_expression));
163
164 // Cache expression with sub-domain.
165 cache_expression = "maps.google.com";
166 EXPECT_FALSE(
167 UrlMatchCacheExpression(GURL("https://google.com"), cache_expression));
168 EXPECT_FALSE(UrlMatchCacheExpression(GURL("https://www.google.com"),
169 cache_expression));
170 EXPECT_TRUE(UrlMatchCacheExpression(GURL("https://maps.google.com"),
171 cache_expression));
172 EXPECT_TRUE(UrlMatchCacheExpression(GURL("https://maps.google.com/local/"),
173 cache_expression));
174
175 // Cache expression with path.
176 cache_expression = std::string("evil.com/bad");
177 EXPECT_TRUE(UrlMatchCacheExpression(GURL("http://evil.com/bad/index.html"),
178 cache_expression));
179 EXPECT_FALSE(UrlMatchCacheExpression(GURL("http://evil.com/worse/index.html"),
180 cache_expression));
181 EXPECT_TRUE(UrlMatchCacheExpression(
182 GURL("http://phishing.malware.evil.com/bad/index.html"),
183 cache_expression));
184 }
185
186 TEST_F(PasswordProtectionServiceTest, TestSetGetAndClearCachedVerdict) {
187 // Assume each verdict has a TTL of 10 minutes.
188 LoginReputationClientResponse verdict_proto_1(CreateVerdictProto(
189 LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foo"));
190 LoginReputationClientResponse verdict_proto_2(CreateVerdictProto(
191 LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, "test.com/bar"));
192 LoginReputationClientResponse verdict_proto_3(CreateVerdictProto(
193 LoginReputationClientResponse::PHISHING, 10 * 60, "evil.com"));
194 LoginReputationClientResponse verdict_proto_4(CreateVerdictProto(
195 LoginReputationClientResponse::PHISHING, 10 * 60, "test.com"));
196
197 base::Time now = base::Time::Now();
198 base::Time yesterday =
199 base::Time::FromDoubleT(now.ToDoubleT() - 24.0 * 60.0 * 60.0);
200 base::Time one_minute_ago = base::Time::FromDoubleT(now.ToDoubleT() - 60.0);
201 password_protection_service_->CacheVerdict(
202 GURL("http://www.test.com/foo/index.html"), &verdict_proto_1, now,
203 content_setting_map_.get());
204 password_protection_service_->CacheVerdict(
205 GURL("http://www.test.com/bar/index.html"), &verdict_proto_2, yesterday,
206 content_setting_map_.get());
207 password_protection_service_->CacheVerdict(
208 GURL("http://phishing.evil.com/local/login.html"), &verdict_proto_3,
209 one_minute_ago, content_setting_map_.get());
210 password_protection_service_->CacheVerdict(
211 GURL("http://www.test.com/index.html"), &verdict_proto_4, now,
212 content_setting_map_.get());
213
214 // Return VERDICT_TYPE_UNSPECIFIED if content setting map has nothing of this
215 // origin.
216 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED,
217 password_protection_service_->GetCachedVerdict(
218 content_setting_map_.get(),
219 GURL("http://www.unkown.com/index.html")));
220
221 // Return VERDICT_TYPE_UNSPECIFIED if verdict is expired.
222 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED,
223 password_protection_service_->GetCachedVerdict(
224 content_setting_map_.get(),
225 GURL("http://www.test.com/bar/test.html")));
226
227 // Return the verdict type associated with the most specific cache expression
228 // if verdict is available and not expired.
229 EXPECT_EQ(LoginReputationClientResponse::SAFE,
230 password_protection_service_->GetCachedVerdict(
231 content_setting_map_.get(),
232 GURL("http://www.test.com/foo/index1.html")));
233 EXPECT_EQ(LoginReputationClientResponse::PHISHING,
234 password_protection_service_->GetCachedVerdict(
235 content_setting_map_.get(),
236 GURL("http://phishing.evil.com/phishing/")));
237
238 // Cache www.test.com/bar again, but this time it is not expired.
239 password_protection_service_->CacheVerdict(
240 GURL("http://www.test.com/bar/index.html"), &verdict_proto_2, now,
241 content_setting_map_.get());
242 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION,
243 password_protection_service_->GetCachedVerdict(
244 content_setting_map_.get(),
245 GURL("http://www.test.com/bar/test2.html")));
246
247 // Now, there should be cached verdicts for 2 origins: http://www.test.com,
248 // and http://phishing.evil.com
249 ContentSettingsForOneType password_protection_settings;
250 content_setting_map_->GetSettingsForOneType(
251 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(),
252 &password_protection_settings);
253 EXPECT_EQ(2U, password_protection_settings.size());
254
255 history::URLRows deleted_urls;
256 deleted_urls.push_back(
257 history::URLRow(GURL("http://phishing.evil.com/phishing/")));
258 // We delete the history of http://phishing.evil.com/phishing.
259 password_protection_service_->RemoveContentSettingsOnURLsDeleted(
260 false, deleted_urls, content_setting_map_.get());
261 content_setting_map_->GetSettingsForOneType(
262 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(),
263 &password_protection_settings);
264 EXPECT_EQ(1U, password_protection_settings.size());
265 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION,
266 password_protection_service_->GetCachedVerdict(
267 content_setting_map_.get(),
268 GURL("http://www.test.com/bar/test2.html")));
269
270 // Now we delete all history. All password protection content settings will be
271 // gone too.
272 password_protection_service_->RemoveContentSettingsOnURLsDeleted(
273 true, deleted_urls, content_setting_map_.get());
274 content_setting_map_->GetSettingsForOneType(
275 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(),
276 &password_protection_settings);
277 EXPECT_EQ(0U, password_protection_settings.size());
278 }
279
88 } // namespace safe_browsing 280 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698