1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/safe_browsing/core/db/v4_local_database_manager.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/run_loop.h"
16 #include "base/sequenced_task_runner.h"
17 #include "base/strings/string_tokenizer.h"
18 #include "base/test/metrics/histogram_tester.h"
19 #include "base/test/scoped_feature_list.h"
20 #include "base/test/test_simple_task_runner.h"
21 #include "base/threading/thread_task_runner_handle.h"
22 #include "components/safe_browsing/core/common/test_task_environment.h"
23 #include "components/safe_browsing/core/db/v4_database.h"
24 #include "components/safe_browsing/core/db/v4_protocol_manager_util.h"
25 #include "components/safe_browsing/core/db/v4_test_util.h"
26 #include "components/safe_browsing/core/features.h"
27 #include "crypto/sha2.h"
28 #include "services/network/public/cpp/shared_url_loader_factory.h"
29 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
30 #include "services/network/test/test_url_loader_factory.h"
31 #include "testing/platform_test.h"
32
33 namespace safe_browsing {
34
35 namespace {
36
37 typedef std::vector<FullHashInfo> FullHashInfos;
38
39 // Utility function for populating hashes.
HashForUrl(const GURL & url)40 FullHash HashForUrl(const GURL& url) {
41 std::vector<FullHash> full_hashes;
42 V4ProtocolManagerUtil::UrlToFullHashes(url, &full_hashes);
43 // ASSERT_GE(full_hashes.size(), 1u);
44 return full_hashes[0];
45 }
46
47 // Use this if you want GetFullHashes() to always return prescribed results.
48 class FakeGetHashProtocolManager : public V4GetHashProtocolManager {
49 public:
FakeGetHashProtocolManager(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,const StoresToCheck & stores_to_check,const V4ProtocolConfig & config,const FullHashInfos & full_hash_infos)50 FakeGetHashProtocolManager(
51 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
52 const StoresToCheck& stores_to_check,
53 const V4ProtocolConfig& config,
54 const FullHashInfos& full_hash_infos)
55 : V4GetHashProtocolManager(url_loader_factory, stores_to_check, config),
56 full_hash_infos_(full_hash_infos) {}
57
GetFullHashes(const FullHashToStoreAndHashPrefixesMap,const std::vector<std::string> &,FullHashCallback callback)58 void GetFullHashes(const FullHashToStoreAndHashPrefixesMap,
59 const std::vector<std::string>&,
60 FullHashCallback callback) override {
61 // Async, since the real manager might use a fetcher.
62 base::ThreadTaskRunnerHandle::Get()->PostTask(
63 FROM_HERE, base::BindOnce(std::move(callback), full_hash_infos_));
64 }
65
66 private:
67 FullHashInfos full_hash_infos_;
68 };
69
70 class FakeGetHashProtocolManagerFactory
71 : public V4GetHashProtocolManagerFactory {
72 public:
FakeGetHashProtocolManagerFactory(const FullHashInfos & full_hash_infos)73 FakeGetHashProtocolManagerFactory(const FullHashInfos& full_hash_infos)
74 : full_hash_infos_(full_hash_infos) {}
75
CreateProtocolManager(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,const StoresToCheck & stores_to_check,const V4ProtocolConfig & config)76 std::unique_ptr<V4GetHashProtocolManager> CreateProtocolManager(
77 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
78 const StoresToCheck& stores_to_check,
79 const V4ProtocolConfig& config) override {
80 return std::make_unique<FakeGetHashProtocolManager>(
81 url_loader_factory, stores_to_check, config, full_hash_infos_);
82 }
83
84 private:
85 FullHashInfos full_hash_infos_;
86 };
87
88 // Use FakeGetHashProtocolManagerFactory in scope, then reset.
89 // You should make sure the DatabaseManager is created _after_ this.
90 class ScopedFakeGetHashProtocolManagerFactory {
91 public:
ScopedFakeGetHashProtocolManagerFactory(const FullHashInfos & full_hash_infos)92 ScopedFakeGetHashProtocolManagerFactory(
93 const FullHashInfos& full_hash_infos) {
94 V4GetHashProtocolManager::RegisterFactory(
95 std::make_unique<FakeGetHashProtocolManagerFactory>(full_hash_infos));
96 }
~ScopedFakeGetHashProtocolManagerFactory()97 ~ScopedFakeGetHashProtocolManagerFactory() {
98 V4GetHashProtocolManager::RegisterFactory(nullptr);
99 }
100 };
101
102 } // namespace
103
104 class FakeV4Database : public V4Database {
105 public:
Create(const scoped_refptr<base::SequencedTaskRunner> & db_task_runner,std::unique_ptr<StoreMap> store_map,const StoreAndHashPrefixes & store_and_hash_prefixes,NewDatabaseReadyCallback new_db_callback,bool stores_available)106 static void Create(
107 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
108 std::unique_ptr<StoreMap> store_map,
109 const StoreAndHashPrefixes& store_and_hash_prefixes,
110 NewDatabaseReadyCallback new_db_callback,
111 bool stores_available) {
112 // Mimics V4Database::Create
113 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner =
114 base::ThreadTaskRunnerHandle::Get();
115 db_task_runner->PostTask(
116 FROM_HERE,
117 base::BindOnce(&FakeV4Database::CreateOnTaskRunner, db_task_runner,
118 std::move(store_map), store_and_hash_prefixes,
119 callback_task_runner, std::move(new_db_callback),
120 stores_available));
121 }
122
123 // V4Database implementation
GetStoresMatchingFullHash(const FullHash & full_hash,const StoresToCheck & stores_to_check,StoreAndHashPrefixes * store_and_hash_prefixes)124 void GetStoresMatchingFullHash(
125 const FullHash& full_hash,
126 const StoresToCheck& stores_to_check,
127 StoreAndHashPrefixes* store_and_hash_prefixes) override {
128 store_and_hash_prefixes->clear();
129 for (const StoreAndHashPrefix& stored_sahp : store_and_hash_prefixes_) {
130 if (stores_to_check.count(stored_sahp.list_id) == 0)
131 continue;
132 const PrefixSize& prefix_size = stored_sahp.hash_prefix.size();
133 if (!full_hash.compare(0, prefix_size, stored_sahp.hash_prefix)) {
134 store_and_hash_prefixes->push_back(stored_sahp);
135 }
136 }
137 }
138
AreAllStoresAvailable(const StoresToCheck & stores_to_check) const139 bool AreAllStoresAvailable(
140 const StoresToCheck& stores_to_check) const override {
141 return stores_available_;
142 }
143
AreAnyStoresAvailable(const StoresToCheck & stores_to_check) const144 bool AreAnyStoresAvailable(
145 const StoresToCheck& stores_to_check) const override {
146 return stores_available_;
147 }
148
149 private:
CreateOnTaskRunner(const scoped_refptr<base::SequencedTaskRunner> & db_task_runner,std::unique_ptr<StoreMap> store_map,const StoreAndHashPrefixes & store_and_hash_prefixes,const scoped_refptr<base::SingleThreadTaskRunner> & callback_task_runner,NewDatabaseReadyCallback new_db_callback,bool stores_available)150 static void CreateOnTaskRunner(
151 const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
152 std::unique_ptr<StoreMap> store_map,
153 const StoreAndHashPrefixes& store_and_hash_prefixes,
154 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner,
155 NewDatabaseReadyCallback new_db_callback,
156 bool stores_available) {
157 // Mimics the semantics of V4Database::CreateOnTaskRunner
158 std::unique_ptr<FakeV4Database> fake_v4_database(
159 new FakeV4Database(db_task_runner, std::move(store_map),
160 store_and_hash_prefixes, stores_available));
161 callback_task_runner->PostTask(FROM_HERE,
162 base::BindOnce(std::move(new_db_callback),
163 std::move(fake_v4_database)));
164 }
165
FakeV4Database(const scoped_refptr<base::SequencedTaskRunner> & db_task_runner,std::unique_ptr<StoreMap> store_map,const StoreAndHashPrefixes & store_and_hash_prefixes,bool stores_available)166 FakeV4Database(const scoped_refptr<base::SequencedTaskRunner>& db_task_runner,
167 std::unique_ptr<StoreMap> store_map,
168 const StoreAndHashPrefixes& store_and_hash_prefixes,
169 bool stores_available)
170 : V4Database(db_task_runner, std::move(store_map)),
171 store_and_hash_prefixes_(store_and_hash_prefixes),
172 stores_available_(stores_available) {}
173
174 const StoreAndHashPrefixes store_and_hash_prefixes_;
175 const bool stores_available_;
176 };
177
178 // TODO(nparker): This might be simpler with a mock and EXPECT calls.
179 // That would also catch unexpected calls.
180 class TestClient : public SafeBrowsingDatabaseManager::Client {
181 public:
TestClient(SBThreatType sb_threat_type,const GURL & url,V4LocalDatabaseManager * manager_to_cancel=nullptr)182 TestClient(SBThreatType sb_threat_type,
183 const GURL& url,
184 V4LocalDatabaseManager* manager_to_cancel = nullptr)
185 : expected_sb_threat_type_(sb_threat_type),
186 expected_urls_(1, url),
187 manager_to_cancel_(manager_to_cancel) {}
188
TestClient(SBThreatType sb_threat_type,const std::vector<GURL> & url_chain)189 TestClient(SBThreatType sb_threat_type, const std::vector<GURL>& url_chain)
190 : expected_sb_threat_type_(sb_threat_type), expected_urls_(url_chain) {}
191
OnCheckBrowseUrlResult(const GURL & url,SBThreatType threat_type,const ThreatMetadata & metadata)192 void OnCheckBrowseUrlResult(const GURL& url,
193 SBThreatType threat_type,
194 const ThreatMetadata& metadata) override {
195 ASSERT_EQ(expected_urls_[0], url);
196 ASSERT_EQ(expected_sb_threat_type_, threat_type);
197 on_check_browse_url_result_called_ = true;
198 if (manager_to_cancel_) {
199 manager_to_cancel_->CancelCheck(this);
200 }
201 }
202
OnCheckResourceUrlResult(const GURL & url,SBThreatType threat_type,const std::string & threat_hash)203 void OnCheckResourceUrlResult(const GURL& url,
204 SBThreatType threat_type,
205 const std::string& threat_hash) override {
206 ASSERT_EQ(expected_urls_[0], url);
207 ASSERT_EQ(expected_sb_threat_type_, threat_type);
208 ASSERT_EQ(threat_type == SB_THREAT_TYPE_SAFE, threat_hash.empty());
209 on_check_resource_url_result_called_ = true;
210 }
211
OnCheckDownloadUrlResult(const std::vector<GURL> & url_chain,SBThreatType threat_type)212 void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
213 SBThreatType threat_type) override {
214 ASSERT_EQ(expected_urls_, url_chain);
215 ASSERT_EQ(expected_sb_threat_type_, threat_type);
216 on_check_download_urls_result_called_ = true;
217 }
218
mutable_expected_urls()219 std::vector<GURL>* mutable_expected_urls() { return &expected_urls_; }
220
on_check_browse_url_result_called()221 bool on_check_browse_url_result_called() {
222 return on_check_browse_url_result_called_;
223 }
on_check_download_urls_result_called()224 bool on_check_download_urls_result_called() {
225 return on_check_download_urls_result_called_;
226 }
on_check_resource_url_result_called()227 bool on_check_resource_url_result_called() {
228 return on_check_resource_url_result_called_;
229 }
230
231 private:
232 const SBThreatType expected_sb_threat_type_;
233 std::vector<GURL> expected_urls_;
234 bool on_check_browse_url_result_called_ = false;
235 bool on_check_download_urls_result_called_ = false;
236 bool on_check_resource_url_result_called_ = false;
237 V4LocalDatabaseManager* manager_to_cancel_;
238 };
239
240 class TestAllowlistClient : public SafeBrowsingDatabaseManager::Client {
241 public:
242 // |match_expected| specifies whether a full hash match is expected.
243 // |expected_sb_threat_type| identifies which callback method to expect to get
244 // called.
TestAllowlistClient(bool match_expected,SBThreatType expected_sb_threat_type)245 explicit TestAllowlistClient(bool match_expected,
246 SBThreatType expected_sb_threat_type)
247 : expected_sb_threat_type_(expected_sb_threat_type),
248 match_expected_(match_expected) {}
249
OnCheckWhitelistUrlResult(bool is_allowlisted)250 void OnCheckWhitelistUrlResult(bool is_allowlisted) override {
251 EXPECT_EQ(match_expected_, is_allowlisted);
252 EXPECT_EQ(SB_THREAT_TYPE_CSD_WHITELIST, expected_sb_threat_type_);
253 callback_called_ = true;
254 }
255
OnCheckUrlForHighConfidenceAllowlist(bool is_allowlisted)256 void OnCheckUrlForHighConfidenceAllowlist(bool is_allowlisted) override {
257 EXPECT_EQ(match_expected_, is_allowlisted);
258 EXPECT_EQ(SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST,
259 expected_sb_threat_type_);
260 callback_called_ = true;
261 }
262
callback_called()263 bool callback_called() { return callback_called_; }
264
265 private:
266 const SBThreatType expected_sb_threat_type_;
267 const bool match_expected_;
268 bool callback_called_ = false;
269 };
270
271 class TestExtensionClient : public SafeBrowsingDatabaseManager::Client {
272 public:
TestExtensionClient(const std::set<FullHash> & expected_bad_crxs)273 TestExtensionClient(const std::set<FullHash>& expected_bad_crxs)
274 : expected_bad_crxs_(expected_bad_crxs),
275 on_check_extensions_result_called_(false) {}
276
OnCheckExtensionsResult(const std::set<FullHash> & bad_crxs)277 void OnCheckExtensionsResult(const std::set<FullHash>& bad_crxs) override {
278 EXPECT_EQ(expected_bad_crxs_, bad_crxs);
279 on_check_extensions_result_called_ = true;
280 }
281
on_check_extensions_result_called()282 bool on_check_extensions_result_called() {
283 return on_check_extensions_result_called_;
284 }
285
286 private:
287 const std::set<FullHash> expected_bad_crxs_;
288 bool on_check_extensions_result_called_;
289 };
290
291 class FakeV4LocalDatabaseManager : public V4LocalDatabaseManager {
292 public:
FakeV4LocalDatabaseManager(const base::FilePath & base_path,ExtendedReportingLevelCallback extended_reporting_level_callback,scoped_refptr<base::SequencedTaskRunner> task_runner)293 FakeV4LocalDatabaseManager(
294 const base::FilePath& base_path,
295 ExtendedReportingLevelCallback extended_reporting_level_callback,
296 scoped_refptr<base::SequencedTaskRunner> task_runner)
297 : V4LocalDatabaseManager(base_path,
298 extended_reporting_level_callback,
299 task_runner),
300 perform_full_hash_check_called_(false) {}
301
302 // V4LocalDatabaseManager impl:
PerformFullHashCheck(std::unique_ptr<PendingCheck> check)303 void PerformFullHashCheck(std::unique_ptr<PendingCheck> check) override {
304 perform_full_hash_check_called_ = true;
305 }
306
PerformFullHashCheckCalled(scoped_refptr<safe_browsing::V4LocalDatabaseManager> & v4_ldbm)307 static bool PerformFullHashCheckCalled(
308 scoped_refptr<safe_browsing::V4LocalDatabaseManager>& v4_ldbm) {
309 FakeV4LocalDatabaseManager* fake =
310 static_cast<FakeV4LocalDatabaseManager*>(v4_ldbm.get());
311 return fake->perform_full_hash_check_called_;
312 }
313
314 private:
~FakeV4LocalDatabaseManager()315 ~FakeV4LocalDatabaseManager() override {}
316
317 bool perform_full_hash_check_called_;
318 };
319
320 class V4LocalDatabaseManagerTest : public PlatformTest {
321 public:
V4LocalDatabaseManagerTest()322 V4LocalDatabaseManagerTest() : task_runner_(new base::TestSimpleTaskRunner) {}
323
SetUp()324 void SetUp() override {
325 PlatformTest::SetUp();
326
327 task_environment_ = CreateTestTaskEnvironment();
328
329 test_shared_loader_factory_ =
330 base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
331 &test_url_loader_factory_);
332
333 ASSERT_TRUE(base_dir_.CreateUniqueTempDir());
334 DVLOG(1) << "base_dir_: " << base_dir_.GetPath().value();
335
336 extended_reporting_level_ = SBER_LEVEL_OFF;
337 erl_callback_ = base::BindRepeating(
338 &V4LocalDatabaseManagerTest::GetExtendedReportingLevel,
339 base::Unretained(this));
340
341 v4_local_database_manager_ =
342 base::WrapRefCounted(new V4LocalDatabaseManager(
343 base_dir_.GetPath(), erl_callback_, task_runner_));
344
345 StartLocalDatabaseManager();
346 }
347
TearDown()348 void TearDown() override {
349 StopLocalDatabaseManager();
350
351 PlatformTest::TearDown();
352 }
353
ForceDisableLocalDatabaseManager()354 void ForceDisableLocalDatabaseManager() {
355 v4_local_database_manager_->enabled_ = false;
356 }
357
ForceEnableLocalDatabaseManager()358 void ForceEnableLocalDatabaseManager() {
359 v4_local_database_manager_->enabled_ = true;
360 }
361
GetQueuedChecks()362 const V4LocalDatabaseManager::QueuedChecks& GetQueuedChecks() {
363 return v4_local_database_manager_->queued_checks_;
364 }
365
GetExtendedReportingLevel()366 ExtendedReportingLevel GetExtendedReportingLevel() {
367 return extended_reporting_level_;
368 }
369
PopulateArtificialDatabase()370 void PopulateArtificialDatabase() {
371 v4_local_database_manager_->PopulateArtificialDatabase();
372 }
373
ReplaceV4Database(const StoreAndHashPrefixes & store_and_hash_prefixes,bool stores_available=false)374 void ReplaceV4Database(const StoreAndHashPrefixes& store_and_hash_prefixes,
375 bool stores_available = false) {
376 // Disable the V4LocalDatabaseManager first so that if the callback to
377 // verify checksum has been scheduled, then it doesn't do anything when it
378 // is called back.
379 ForceDisableLocalDatabaseManager();
380 // Wait to make sure that the callback gets executed if it has already been
381 // scheduled.
382 WaitForTasksOnTaskRunner();
383 // Re-enable the V4LocalDatabaseManager otherwise the checks won't work and
384 // the fake database won't be set either.
385 ForceEnableLocalDatabaseManager();
386
387 NewDatabaseReadyCallback db_ready_callback =
388 base::BindOnce(&V4LocalDatabaseManager::DatabaseReadyForChecks,
389 base::Unretained(v4_local_database_manager_.get()));
390 FakeV4Database::Create(task_runner_, std::make_unique<StoreMap>(),
391 store_and_hash_prefixes,
392 std::move(db_ready_callback), stores_available);
393 WaitForTasksOnTaskRunner();
394 }
395
ResetLocalDatabaseManager()396 void ResetLocalDatabaseManager() {
397 StopLocalDatabaseManager();
398 v4_local_database_manager_ =
399 base::WrapRefCounted(new V4LocalDatabaseManager(
400 base_dir_.GetPath(), erl_callback_, task_runner_));
401 StartLocalDatabaseManager();
402 }
403
ResetV4Database()404 void ResetV4Database() {
405 V4Database::Destroy(std::move(v4_local_database_manager_->v4_database_));
406 }
407
StartLocalDatabaseManager()408 void StartLocalDatabaseManager() {
409 v4_local_database_manager_->StartOnIOThread(test_shared_loader_factory_,
410 GetTestV4ProtocolConfig());
411 }
412
StopLocalDatabaseManager()413 void StopLocalDatabaseManager() {
414 if (v4_local_database_manager_) {
415 v4_local_database_manager_->StopOnIOThread(true);
416 }
417
418 // Force destruction of the database.
419 WaitForTasksOnTaskRunner();
420 }
421
WaitForTasksOnTaskRunner()422 void WaitForTasksOnTaskRunner() {
423 // Wait for tasks on the task runner so we're sure that the
424 // V4LocalDatabaseManager has read the data from disk.
425 task_runner_->RunPendingTasks();
426 base::RunLoop().RunUntilIdle();
427 }
428
429 // For those tests that need the fake manager
SetupFakeManager()430 void SetupFakeManager() {
431 // StopLocalDatabaseManager before resetting it because that's what
432 // ~V4LocalDatabaseManager expects.
433 StopLocalDatabaseManager();
434 v4_local_database_manager_ =
435 base::WrapRefCounted(new FakeV4LocalDatabaseManager(
436 base_dir_.GetPath(), erl_callback_, task_runner_));
437 StartLocalDatabaseManager();
438 WaitForTasksOnTaskRunner();
439 }
440
441 const SBThreatTypeSet usual_threat_types_ = CreateSBThreatTypeSet(
442 {SB_THREAT_TYPE_URL_PHISHING, SB_THREAT_TYPE_URL_MALWARE,
443 SB_THREAT_TYPE_URL_UNWANTED});
444
445 network::TestURLLoaderFactory test_url_loader_factory_;
446 scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
447 base::ScopedTempDir base_dir_;
448 ExtendedReportingLevel extended_reporting_level_;
449 ExtendedReportingLevelCallback erl_callback_;
450 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
451 std::unique_ptr<base::test::TaskEnvironment> task_environment_;
452 scoped_refptr<V4LocalDatabaseManager> v4_local_database_manager_;
453 };
454
TEST_F(V4LocalDatabaseManagerTest,TestGetThreatSource)455 TEST_F(V4LocalDatabaseManagerTest, TestGetThreatSource) {
456 WaitForTasksOnTaskRunner();
457 EXPECT_EQ(ThreatSource::LOCAL_PVER4,
458 v4_local_database_manager_->GetThreatSource());
459 }
460
TEST_F(V4LocalDatabaseManagerTest,TestIsSupported)461 TEST_F(V4LocalDatabaseManagerTest, TestIsSupported) {
462 WaitForTasksOnTaskRunner();
463 EXPECT_TRUE(v4_local_database_manager_->IsSupported());
464 }
465
TEST_F(V4LocalDatabaseManagerTest,TestCanCheckUrl)466 TEST_F(V4LocalDatabaseManagerTest, TestCanCheckUrl) {
467 WaitForTasksOnTaskRunner();
468 EXPECT_TRUE(
469 v4_local_database_manager_->CanCheckUrl(GURL("http://example.com/a/")));
470 EXPECT_TRUE(
471 v4_local_database_manager_->CanCheckUrl(GURL("https://example.com/a/")));
472 EXPECT_TRUE(
473 v4_local_database_manager_->CanCheckUrl(GURL("ftp://example.com/a/")));
474 EXPECT_FALSE(
475 v4_local_database_manager_->CanCheckUrl(GURL("adp://example.com/a/")));
476 }
477
TEST_F(V4LocalDatabaseManagerTest,TestCheckBrowseUrlWithEmptyStoresReturnsNoMatch)478 TEST_F(V4LocalDatabaseManagerTest,
479 TestCheckBrowseUrlWithEmptyStoresReturnsNoMatch) {
480 WaitForTasksOnTaskRunner();
481 // Both the stores are empty right now so CheckBrowseUrl should return true.
482 EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
483 GURL("http://example.com/a/"), usual_threat_types_, nullptr));
484 }
485
TEST_F(V4LocalDatabaseManagerTest,TestCheckBrowseUrlWithFakeDbReturnsMatch)486 TEST_F(V4LocalDatabaseManagerTest, TestCheckBrowseUrlWithFakeDbReturnsMatch) {
487 WaitForTasksOnTaskRunner();
488
489 std::string url_bad_no_scheme("example.com/bad/");
490 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
491 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
492 StoreAndHashPrefixes store_and_hash_prefixes;
493 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), bad_hash_prefix);
494 ReplaceV4Database(store_and_hash_prefixes);
495
496 const GURL url_bad("https://" + url_bad_no_scheme);
497 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
498 url_bad, usual_threat_types_, nullptr));
499
500 // Wait for PerformFullHashCheck to complete.
501 WaitForTasksOnTaskRunner();
502 }
503
TEST_F(V4LocalDatabaseManagerTest,TestCheckCsdWhitelistWithPrefixMatch)504 TEST_F(V4LocalDatabaseManagerTest, TestCheckCsdWhitelistWithPrefixMatch) {
505 // Setup to receive full-hash misses. We won't make URL requests.
506 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
507 ResetLocalDatabaseManager();
508 WaitForTasksOnTaskRunner();
509
510 std::string url_safe_no_scheme("example.com/safe/");
511 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
512 const HashPrefix safe_hash_prefix(safe_full_hash.substr(0, 5));
513 StoreAndHashPrefixes store_and_hash_prefixes;
514 store_and_hash_prefixes.emplace_back(GetUrlCsdWhitelistId(),
515 safe_hash_prefix);
516 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
517
518 TestAllowlistClient client(
519 /* match_expected= */ false,
520 /* expected_sb_threat_type= */ SB_THREAT_TYPE_CSD_WHITELIST);
521 const GURL url_check("https://" + url_safe_no_scheme);
522 EXPECT_EQ(AsyncMatch::ASYNC, v4_local_database_manager_->CheckCsdWhitelistUrl(
523 url_check, &client));
524
525 EXPECT_FALSE(client.callback_called());
526
527 // Wait for PerformFullHashCheck to complete.
528 WaitForTasksOnTaskRunner();
529 EXPECT_TRUE(client.callback_called());
530 }
531
532 // This is like CsdWhitelistWithPrefixMatch, but we also verify the
533 // full-hash-match results in an appropriate callback value.
TEST_F(V4LocalDatabaseManagerTest,TestCheckCsdWhitelistWithPrefixTheFullMatch)534 TEST_F(V4LocalDatabaseManagerTest,
535 TestCheckCsdWhitelistWithPrefixTheFullMatch) {
536 std::string url_safe_no_scheme("example.com/safe/");
537 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
538
539 // Setup to receive full-hash hit. We won't make URL requests.
540 FullHashInfos infos(
541 {{safe_full_hash, GetUrlCsdWhitelistId(), base::Time::Now()}});
542 ScopedFakeGetHashProtocolManagerFactory pin(infos);
543 ResetLocalDatabaseManager();
544 WaitForTasksOnTaskRunner();
545
546 const HashPrefix safe_hash_prefix(safe_full_hash.substr(0, 5));
547 StoreAndHashPrefixes store_and_hash_prefixes;
548 store_and_hash_prefixes.emplace_back(GetUrlCsdWhitelistId(),
549 safe_hash_prefix);
550 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
551
552 TestAllowlistClient client(
553 /* match_expected= */ true,
554 /* expected_sb_threat_type= */ SB_THREAT_TYPE_CSD_WHITELIST);
555 const GURL url_check("https://" + url_safe_no_scheme);
556 EXPECT_EQ(AsyncMatch::ASYNC, v4_local_database_manager_->CheckCsdWhitelistUrl(
557 url_check, &client));
558
559 EXPECT_FALSE(client.callback_called());
560
561 // Wait for PerformFullHashCheck to complete.
562 WaitForTasksOnTaskRunner();
563 EXPECT_TRUE(client.callback_called());
564 }
565
TEST_F(V4LocalDatabaseManagerTest,TestCheckCsdWhitelistWithFullMatch)566 TEST_F(V4LocalDatabaseManagerTest, TestCheckCsdWhitelistWithFullMatch) {
567 // Setup to receive full-hash misses. We won't make URL requests.
568 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
569 ResetLocalDatabaseManager();
570 WaitForTasksOnTaskRunner();
571
572 std::string url_safe_no_scheme("example.com/safe/");
573 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
574 StoreAndHashPrefixes store_and_hash_prefixes;
575 store_and_hash_prefixes.emplace_back(GetUrlCsdWhitelistId(), safe_full_hash);
576 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
577
578 TestAllowlistClient client(
579 /* match_expected= */ false,
580 /* expected_sb_threat_type= */ SB_THREAT_TYPE_CSD_WHITELIST);
581 const GURL url_check("https://" + url_safe_no_scheme);
582 EXPECT_EQ(AsyncMatch::MATCH, v4_local_database_manager_->CheckCsdWhitelistUrl(
583 url_check, &client));
584
585 WaitForTasksOnTaskRunner();
586 EXPECT_FALSE(client.callback_called());
587 }
588
TEST_F(V4LocalDatabaseManagerTest,TestCheckCsdWhitelistWithNoMatch)589 TEST_F(V4LocalDatabaseManagerTest, TestCheckCsdWhitelistWithNoMatch) {
590 // Setup to receive full-hash misses. We won't make URL requests.
591 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
592 ResetLocalDatabaseManager();
593 WaitForTasksOnTaskRunner();
594
595 // Add a full hash that won't match the URL we check.
596 std::string url_safe_no_scheme("example.com/safe/");
597 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
598 StoreAndHashPrefixes store_and_hash_prefixes;
599 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), safe_full_hash);
600 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
601
602 TestAllowlistClient client(
603 /* match_expected= */ true,
604 /* expected_sb_threat_type= */ SB_THREAT_TYPE_CSD_WHITELIST);
605 const GURL url_check("https://other.com/");
606 EXPECT_EQ(
607 AsyncMatch::NO_MATCH,
608 v4_local_database_manager_->CheckCsdWhitelistUrl(url_check, &client));
609
610 WaitForTasksOnTaskRunner();
611 EXPECT_FALSE(client.callback_called());
612 }
613
614 // When allowlist is unavailable, all URLS should be allowed.
TEST_F(V4LocalDatabaseManagerTest,TestCheckCsdWhitelistUnavailable)615 TEST_F(V4LocalDatabaseManagerTest, TestCheckCsdWhitelistUnavailable) {
616 // Setup to receive full-hash misses. We won't make URL requests.
617 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
618 ResetLocalDatabaseManager();
619 WaitForTasksOnTaskRunner();
620
621 StoreAndHashPrefixes store_and_hash_prefixes;
622 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ false);
623
624 TestAllowlistClient client(
625 /* match_expected= */ false,
626 /* expected_sb_threat_type= */ SB_THREAT_TYPE_CSD_WHITELIST);
627 const GURL url_check("https://other.com/");
628 EXPECT_EQ(AsyncMatch::MATCH, v4_local_database_manager_->CheckCsdWhitelistUrl(
629 url_check, &client));
630
631 WaitForTasksOnTaskRunner();
632 EXPECT_FALSE(client.callback_called());
633 }
634
TEST_F(V4LocalDatabaseManagerTest,TestCheckBrowseUrlReturnsNoMatchWhenDisabled)635 TEST_F(V4LocalDatabaseManagerTest,
636 TestCheckBrowseUrlReturnsNoMatchWhenDisabled) {
637 WaitForTasksOnTaskRunner();
638
639 // The same URL returns |false| in the previous test because
640 // v4_local_database_manager_ is enabled.
641 ForceDisableLocalDatabaseManager();
642
643 EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
644 GURL("http://example.com/a/"), usual_threat_types_, nullptr));
645 }
646
647 // Hash prefix matches on the high confidence allowlist, but full hash match
648 // fails.
TEST_F(V4LocalDatabaseManagerTest,TestCheckUrlForHCAllowlistWithPrefixMatchButNoFullHashMatch)649 TEST_F(V4LocalDatabaseManagerTest,
650 TestCheckUrlForHCAllowlistWithPrefixMatchButNoFullHashMatch) {
651 base::test::ScopedFeatureList feature_list;
652 feature_list.InitWithFeatures({safe_browsing::kRealTimeUrlLookupEnabled}, {});
653
654 std::string url_safe_no_scheme("example.com/safe/");
655 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
656
657 // Setup to receive full-hash misses. We won't make URL requests.
658 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
659 ResetLocalDatabaseManager();
660 WaitForTasksOnTaskRunner();
661
662 // Setup to match hash prefix in the local database.
663 const HashPrefix safe_hash_prefix(safe_full_hash.substr(0, 5));
664 StoreAndHashPrefixes store_and_hash_prefixes;
665 store_and_hash_prefixes.emplace_back(GetUrlHighConfidenceAllowlistId(),
666 safe_hash_prefix);
667 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
668
669 // Setup the allowlist client to verify the callback.
670 TestAllowlistClient client(
671 /* match_expected= */ false,
672 /* expected_sb_threat_type= */ SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST);
673
674 // Lookup the high confidence allowlist.
675 const GURL url_check("https://" + url_safe_no_scheme);
676 EXPECT_EQ(AsyncMatch::ASYNC,
677 v4_local_database_manager_->CheckUrlForHighConfidenceAllowlist(
678 url_check, &client));
679
680 EXPECT_FALSE(client.callback_called());
681
682 // Wait for PerformFullHashCheck to complete.
683 WaitForTasksOnTaskRunner();
684 EXPECT_TRUE(client.callback_called());
685 }
686
687 // Hash prefix matches on the high confidence allowlist, and subsequently the
688 // full hash also matches.
TEST_F(V4LocalDatabaseManagerTest,TestCheckUrlForHCAllowlistWithPrefixMatchAndFullHashMatch)689 TEST_F(V4LocalDatabaseManagerTest,
690 TestCheckUrlForHCAllowlistWithPrefixMatchAndFullHashMatch) {
691 base::test::ScopedFeatureList feature_list;
692 feature_list.InitWithFeatures({safe_browsing::kRealTimeUrlLookupEnabled}, {});
693
694 std::string url_safe_no_scheme("example.com/safe/");
695 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
696
697 // Setup to receive full-hash hit. We won't make URL requests.
698 FullHashInfos infos(
699 {{safe_full_hash, GetUrlHighConfidenceAllowlistId(), base::Time::Now()}});
700 ScopedFakeGetHashProtocolManagerFactory pin(infos);
701 ResetLocalDatabaseManager();
702 WaitForTasksOnTaskRunner();
703
704 // Setup to match hash prefix in the local database.
705 const HashPrefix safe_hash_prefix(safe_full_hash.substr(0, 5));
706 StoreAndHashPrefixes store_and_hash_prefixes;
707 store_and_hash_prefixes.emplace_back(GetUrlHighConfidenceAllowlistId(),
708 safe_hash_prefix);
709 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
710
711 // Setup the allowlist client to verify the callback.
712 TestAllowlistClient client(
713 /* match_expected= */ true,
714 /* expected_sb_threat_type= */ SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST);
715
716 // Lookup the high confidence allowlist.
717 const GURL url_check("https://" + url_safe_no_scheme);
718 EXPECT_EQ(AsyncMatch::ASYNC,
719 v4_local_database_manager_->CheckUrlForHighConfidenceAllowlist(
720 url_check, &client));
721
722 EXPECT_FALSE(client.callback_called());
723
724 // Wait for PerformFullHashCheck to complete.
725 WaitForTasksOnTaskRunner();
726 EXPECT_TRUE(client.callback_called());
727 }
728
729 // Full hash match on the high confidence allowlist. Returns |MATCH|
730 // synchronously and callback isn't called.
TEST_F(V4LocalDatabaseManagerTest,TestCheckUrlForHCAllowlistWithLocalFullHashMatch)731 TEST_F(V4LocalDatabaseManagerTest,
732 TestCheckUrlForHCAllowlistWithLocalFullHashMatch) {
733 base::test::ScopedFeatureList feature_list;
734 feature_list.InitWithFeatures({safe_browsing::kRealTimeUrlLookupEnabled}, {});
735
736 std::string url_safe_no_scheme("example.com/safe/");
737 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
738
739 // Setup to receive full-hash misses. We won't make URL requests.
740 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
741 ResetLocalDatabaseManager();
742 WaitForTasksOnTaskRunner();
743
744 // Setup to match full hash in the local database.
745 StoreAndHashPrefixes store_and_hash_prefixes;
746 store_and_hash_prefixes.emplace_back(GetUrlHighConfidenceAllowlistId(),
747 safe_full_hash);
748 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
749
750 // Setup the allowlist client to verify the callback isn't called.
751 TestAllowlistClient client(
752 /* match_expected= */ false,
753 /* expected_sb_threat_type= */ SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST);
754 const GURL url_check("https://" + url_safe_no_scheme);
755 EXPECT_EQ(AsyncMatch::MATCH,
756 v4_local_database_manager_->CheckUrlForHighConfidenceAllowlist(
757 url_check, &client));
758
759 WaitForTasksOnTaskRunner();
760 EXPECT_FALSE(client.callback_called());
761 }
762
763 // Hash prefix has no match on the high confidence allowlist. Returns |NO_MATCH|
764 // synchronously and callback isn't called.
TEST_F(V4LocalDatabaseManagerTest,TestCheckUrlForHCAllowlistWithNoMatch)765 TEST_F(V4LocalDatabaseManagerTest, TestCheckUrlForHCAllowlistWithNoMatch) {
766 base::test::ScopedFeatureList feature_list;
767 feature_list.InitWithFeatures({safe_browsing::kRealTimeUrlLookupEnabled}, {});
768
769 std::string url_safe_no_scheme("example.com/safe/");
770 FullHash safe_full_hash(crypto::SHA256HashString(url_safe_no_scheme));
771
772 // Setup to receive full-hash misses. We won't make URL requests.
773 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
774 ResetLocalDatabaseManager();
775 WaitForTasksOnTaskRunner();
776
777 // Add a full hash that won't match the URL we check.
778 StoreAndHashPrefixes store_and_hash_prefixes;
779 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), safe_full_hash);
780 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
781
782 // Setup the allowlist client to verify the callback isn't called.
783 TestAllowlistClient client(
784 /* match_expected= */ false,
785 /* expected_sb_threat_type= */ SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST);
786 const GURL url_check("https://example.com/other/");
787 EXPECT_EQ(AsyncMatch::NO_MATCH,
788 v4_local_database_manager_->CheckUrlForHighConfidenceAllowlist(
789 url_check, &client));
790
791 WaitForTasksOnTaskRunner();
792 EXPECT_FALSE(client.callback_called());
793 }
794
795 // When allowlist is unavailable, all URLS should be considered MATCH.
TEST_F(V4LocalDatabaseManagerTest,TestCheckUrlForHCAllowlistUnavailable)796 TEST_F(V4LocalDatabaseManagerTest, TestCheckUrlForHCAllowlistUnavailable) {
797 base::test::ScopedFeatureList feature_list;
798 feature_list.InitWithFeatures({safe_browsing::kRealTimeUrlLookupEnabled}, {});
799
800 // Setup to receive full-hash misses. We won't make URL requests.
801 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
802 ResetLocalDatabaseManager();
803 WaitForTasksOnTaskRunner();
804
805 // Setup local database as unavailable.
806 StoreAndHashPrefixes store_and_hash_prefixes;
807 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ false);
808
809 // Setup the allowlist client to verify the callback isn't called.
810 TestAllowlistClient client(
811 /* match_expected= */ false,
812 /* expected_sb_threat_type= */ SB_THREAT_TYPE_HIGH_CONFIDENCE_ALLOWLIST);
813
814 const GURL url_check("https://example.com/safe");
815 EXPECT_EQ(AsyncMatch::MATCH,
816 v4_local_database_manager_->CheckUrlForHighConfidenceAllowlist(
817 url_check, &client));
818
819 WaitForTasksOnTaskRunner();
820 EXPECT_FALSE(client.callback_called());
821 }
822
TEST_F(V4LocalDatabaseManagerTest,TestGetSeverestThreatTypeAndMetadata)823 TEST_F(V4LocalDatabaseManagerTest, TestGetSeverestThreatTypeAndMetadata) {
824 base::HistogramTester histograms;
825 WaitForTasksOnTaskRunner();
826
827 FullHash fh_malware("Malware");
828 FullHashInfo fhi_malware(fh_malware, GetUrlMalwareId(), base::Time::Now());
829 fhi_malware.metadata.population_id = "malware_popid";
830
831 FullHash fh_api("api");
832 FullHashInfo fhi_api(fh_api, GetChromeUrlApiId(), base::Time::Now());
833 fhi_api.metadata.population_id = "api_popid";
834
835 FullHash fh_example("example");
836 std::vector<FullHashInfo> fhis({fhi_malware, fhi_api});
837 std::vector<FullHash> full_hashes({fh_malware, fh_example, fh_api});
838
839 std::vector<SBThreatType> full_hash_threat_types(full_hashes.size(),
840 SB_THREAT_TYPE_SAFE);
841 SBThreatType result_threat_type;
842 ThreatMetadata metadata;
843 FullHash matching_full_hash;
844
845 const std::vector<SBThreatType> expected_full_hash_threat_types(
846 {SB_THREAT_TYPE_URL_MALWARE, SB_THREAT_TYPE_SAFE,
847 SB_THREAT_TYPE_API_ABUSE});
848
849 v4_local_database_manager_->GetSeverestThreatTypeAndMetadata(
850 fhis, full_hashes, &full_hash_threat_types, &result_threat_type,
851 &metadata, &matching_full_hash);
852 EXPECT_EQ(expected_full_hash_threat_types, full_hash_threat_types);
853
854 EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, result_threat_type);
855 EXPECT_EQ("malware_popid", metadata.population_id);
856 EXPECT_EQ(fh_malware, matching_full_hash);
857
858 // Reversing the list has no effect.
859 std::reverse(std::begin(fhis), std::end(fhis));
860 full_hash_threat_types.assign(full_hashes.size(), SB_THREAT_TYPE_SAFE);
861
862 v4_local_database_manager_->GetSeverestThreatTypeAndMetadata(
863 fhis, full_hashes, &full_hash_threat_types, &result_threat_type,
864 &metadata, &matching_full_hash);
865 EXPECT_EQ(expected_full_hash_threat_types, full_hash_threat_types);
866 EXPECT_EQ(SB_THREAT_TYPE_URL_MALWARE, result_threat_type);
867 EXPECT_EQ("malware_popid", metadata.population_id);
868 EXPECT_EQ(fh_malware, matching_full_hash);
869
870 histograms.ExpectUniqueSample(
871 "SafeBrowsing.V4LocalDatabaseManager.ThreatInfoSize",
872 /* sample */ 2, /* expected_count */ 2);
873 }
874
TEST_F(V4LocalDatabaseManagerTest,TestChecksAreQueued)875 TEST_F(V4LocalDatabaseManagerTest, TestChecksAreQueued) {
876 const GURL url("https://www.example.com/");
877 TestClient client(SB_THREAT_TYPE_SAFE, url);
878 EXPECT_TRUE(GetQueuedChecks().empty());
879 v4_local_database_manager_->CheckBrowseUrl(url, usual_threat_types_, &client);
880 // The database is unavailable so the check should get queued.
881 EXPECT_EQ(1ul, GetQueuedChecks().size());
882
883 // The following function waits for the DB to load.
884 WaitForTasksOnTaskRunner();
885 EXPECT_TRUE(GetQueuedChecks().empty());
886
887 ResetV4Database();
888 v4_local_database_manager_->CheckBrowseUrl(url, usual_threat_types_, &client);
889 // The database is unavailable so the check should get queued.
890 EXPECT_EQ(1ul, GetQueuedChecks().size());
891
892 StopLocalDatabaseManager();
893 EXPECT_TRUE(GetQueuedChecks().empty());
894 }
895
896 // Verify that a window where checks cannot be cancelled is closed.
TEST_F(V4LocalDatabaseManagerTest,CancelPending)897 TEST_F(V4LocalDatabaseManagerTest, CancelPending) {
898 // Setup to receive full-hash misses.
899 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
900
901 // Reset the database manager so it picks up the replacement protocol manager.
902 ResetLocalDatabaseManager();
903 WaitForTasksOnTaskRunner();
904
905 // Put a match in the db that will cause a protocol-manager request.
906 std::string url_bad_no_scheme("example.com/bad/");
907 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
908 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
909 StoreAndHashPrefixes store_and_hash_prefixes;
910 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), bad_hash_prefix);
911 ReplaceV4Database(store_and_hash_prefixes);
912
913 const GURL url_bad("https://" + url_bad_no_scheme);
914 // Test that a request flows through to the callback.
915 {
916 TestClient client(SB_THREAT_TYPE_SAFE, url_bad);
917 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
918 url_bad, usual_threat_types_, &client));
919 EXPECT_FALSE(client.on_check_browse_url_result_called());
920 WaitForTasksOnTaskRunner();
921 EXPECT_TRUE(client.on_check_browse_url_result_called());
922 }
923
924 // Test that cancel prevents the callback from being called.
925 {
926 TestClient client(SB_THREAT_TYPE_SAFE, url_bad);
927 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
928 url_bad, usual_threat_types_, &client));
929 v4_local_database_manager_->CancelCheck(&client);
930 EXPECT_FALSE(client.on_check_browse_url_result_called());
931 WaitForTasksOnTaskRunner();
932 EXPECT_FALSE(client.on_check_browse_url_result_called());
933 }
934 }
935
936 // When the database load flushes the queued requests, make sure that
937 // CancelCheck() is not fatal in the client callback.
TEST_F(V4LocalDatabaseManagerTest,CancelQueued)938 TEST_F(V4LocalDatabaseManagerTest, CancelQueued) {
939 const GURL url("http://example.com/a/");
940
941 TestClient client1(SB_THREAT_TYPE_SAFE, url,
942 v4_local_database_manager_.get());
943 TestClient client2(SB_THREAT_TYPE_SAFE, url);
944 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
945 url, usual_threat_types_, &client1));
946 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
947 url, usual_threat_types_, &client2));
948 EXPECT_EQ(2ul, GetQueuedChecks().size());
949 EXPECT_FALSE(client1.on_check_browse_url_result_called());
950 EXPECT_FALSE(client2.on_check_browse_url_result_called());
951 WaitForTasksOnTaskRunner();
952 EXPECT_TRUE(client1.on_check_browse_url_result_called());
953 EXPECT_TRUE(client2.on_check_browse_url_result_called());
954 }
955
956 // This test is somewhat similar to TestCheckBrowseUrlWithFakeDbReturnsMatch but
957 // it uses a fake V4LocalDatabaseManager to assert that PerformFullHashCheck is
958 // called async.
TEST_F(V4LocalDatabaseManagerTest,PerformFullHashCheckCalledAsync)959 TEST_F(V4LocalDatabaseManagerTest, PerformFullHashCheckCalledAsync) {
960 SetupFakeManager();
961
962 std::string url_bad_no_scheme("example.com/bad/");
963 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
964 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
965 StoreAndHashPrefixes store_and_hash_prefixes;
966 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), bad_hash_prefix);
967 ReplaceV4Database(store_and_hash_prefixes);
968
969 const GURL url_bad("https://" + url_bad_no_scheme);
970 // The fake database returns a matched hash prefix.
971 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
972 url_bad, usual_threat_types_, nullptr));
973
974 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
975 v4_local_database_manager_));
976
977 // Wait for PerformFullHashCheck to complete.
978 WaitForTasksOnTaskRunner();
979
980 EXPECT_TRUE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
981 v4_local_database_manager_));
982 }
983
TEST_F(V4LocalDatabaseManagerTest,UsingWeakPtrDropsCallback)984 TEST_F(V4LocalDatabaseManagerTest, UsingWeakPtrDropsCallback) {
985 SetupFakeManager();
986
987 std::string url_bad_no_scheme("example.com/bad/");
988 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
989 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
990 StoreAndHashPrefixes store_and_hash_prefixes;
991 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(), bad_hash_prefix);
992 ReplaceV4Database(store_and_hash_prefixes);
993
994 const GURL url_bad("https://" + url_bad_no_scheme);
995 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
996 url_bad, usual_threat_types_, nullptr));
997 v4_local_database_manager_->StopOnIOThread(true);
998
999 // Release the V4LocalDatabaseManager object right away before the callback
1000 // gets called. When the callback gets called, without using a weak-ptr
1001 // factory, this leads to a use after free. However, using the weak-ptr means
1002 // that the callback is simply dropped.
1003 v4_local_database_manager_ = nullptr;
1004
1005 // Wait for the tasks scheduled by StopOnIOThread to complete.
1006 WaitForTasksOnTaskRunner();
1007 }
1008
TEST_F(V4LocalDatabaseManagerTest,TestMatchDownloadWhitelistString)1009 TEST_F(V4LocalDatabaseManagerTest, TestMatchDownloadWhitelistString) {
1010 SetupFakeManager();
1011 const std::string good_cert = "Good Cert";
1012 const std::string other_cert = "Other Cert";
1013 FullHash good_hash(crypto::SHA256HashString(good_cert));
1014
1015 StoreAndHashPrefixes store_and_hash_prefixes;
1016 store_and_hash_prefixes.emplace_back(GetCertCsdDownloadWhitelistId(),
1017 good_hash);
1018
1019 ReplaceV4Database(store_and_hash_prefixes, false /* not available */);
1020 // Verify it defaults to false when DB is not available.
1021 EXPECT_FALSE(
1022 v4_local_database_manager_->MatchDownloadWhitelistString(good_cert));
1023
1024 ReplaceV4Database(store_and_hash_prefixes, true /* available */);
1025 // Not whitelisted.
1026 EXPECT_FALSE(
1027 v4_local_database_manager_->MatchDownloadWhitelistString(other_cert));
1028 // Whitelisted.
1029 EXPECT_TRUE(
1030 v4_local_database_manager_->MatchDownloadWhitelistString(good_cert));
1031
1032 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1033 v4_local_database_manager_));
1034 }
1035
TEST_F(V4LocalDatabaseManagerTest,TestMatchDownloadWhitelistUrl)1036 TEST_F(V4LocalDatabaseManagerTest, TestMatchDownloadWhitelistUrl) {
1037 SetupFakeManager();
1038 GURL good_url("http://safe.com");
1039 GURL other_url("http://iffy.com");
1040
1041 StoreAndHashPrefixes store_and_hash_prefixes;
1042 store_and_hash_prefixes.emplace_back(GetUrlCsdDownloadWhitelistId(),
1043 HashForUrl(good_url));
1044
1045 ReplaceV4Database(store_and_hash_prefixes, false /* not available */);
1046 // Verify it defaults to false when DB is not available.
1047 EXPECT_FALSE(v4_local_database_manager_->MatchDownloadWhitelistUrl(good_url));
1048
1049 ReplaceV4Database(store_and_hash_prefixes, true /* available */);
1050 // Not whitelisted.
1051 EXPECT_FALSE(
1052 v4_local_database_manager_->MatchDownloadWhitelistUrl(other_url));
1053 // Whitelisted.
1054 EXPECT_TRUE(v4_local_database_manager_->MatchDownloadWhitelistUrl(good_url));
1055
1056 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1057 v4_local_database_manager_));
1058 }
1059
TEST_F(V4LocalDatabaseManagerTest,TestMatchMalwareIP)1060 TEST_F(V4LocalDatabaseManagerTest, TestMatchMalwareIP) {
1061 SetupFakeManager();
1062
1063 // >>> hashlib.sha1(socket.inet_pton(socket.AF_INET6,
1064 // '::ffff:192.168.1.2')).digest() + chr(128)
1065 // '\xb3\xe0z\xafAv#h\x9a\xcf<\xf3ee\x94\xda\xf6y\xb1\xad\x80'
1066 StoreAndHashPrefixes store_and_hash_prefixes;
1067 store_and_hash_prefixes.emplace_back(GetIpMalwareId(),
1068 FullHash("\xB3\xE0z\xAF"
1069 "Av#h\x9A\xCF<\xF3"
1070 "ee\x94\xDA\xF6y\xB1\xAD\x80"));
1071 ReplaceV4Database(store_and_hash_prefixes);
1072
1073 EXPECT_FALSE(v4_local_database_manager_->MatchMalwareIP(""));
1074 // Not blacklisted.
1075 EXPECT_FALSE(v4_local_database_manager_->MatchMalwareIP("192.168.1.1"));
1076 // Blacklisted.
1077 EXPECT_TRUE(v4_local_database_manager_->MatchMalwareIP("192.168.1.2"));
1078
1079 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1080 v4_local_database_manager_));
1081 }
1082
1083 // This verifies the fix for race in http://crbug.com/660293
TEST_F(V4LocalDatabaseManagerTest,TestCheckBrowseUrlWithSameClientAndCancel)1084 TEST_F(V4LocalDatabaseManagerTest, TestCheckBrowseUrlWithSameClientAndCancel) {
1085 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
1086 // Reset the database manager so it picks up the replacement protocol manager.
1087 ResetLocalDatabaseManager();
1088 WaitForTasksOnTaskRunner();
1089
1090 StoreAndHashPrefixes store_and_hash_prefixes;
1091 store_and_hash_prefixes.emplace_back(GetUrlMalwareId(),
1092 HashPrefix("sن\340\t\006_"));
1093 ReplaceV4Database(store_and_hash_prefixes);
1094
1095 GURL first_url("http://example.com/a");
1096 GURL second_url("http://example.com/");
1097 TestClient client(SB_THREAT_TYPE_SAFE, first_url);
1098 // The fake database returns a matched hash prefix.
1099 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1100 first_url, usual_threat_types_, &client));
1101
1102 // That check gets queued. Now, let's cancel the check. After this, we should
1103 // not receive a call for |OnCheckBrowseUrlResult| with |first_url|.
1104 v4_local_database_manager_->CancelCheck(&client);
1105
1106 // Now, re-use that client but for |second_url|.
1107 client.mutable_expected_urls()->assign(1, second_url);
1108 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1109 second_url, usual_threat_types_, &client));
1110
1111 // Wait for PerformFullHashCheck to complete.
1112 WaitForTasksOnTaskRunner();
1113 // |on_check_browse_url_result_called_| is true only if OnCheckBrowseUrlResult
1114 // gets called with the |url| equal to |expected_url|, which is |second_url|
1115 // in
1116 // this test.
1117 EXPECT_TRUE(client.on_check_browse_url_result_called());
1118 }
1119
TEST_F(V4LocalDatabaseManagerTest,TestCheckResourceUrl)1120 TEST_F(V4LocalDatabaseManagerTest, TestCheckResourceUrl) {
1121 // Setup to receive full-hash misses.
1122 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
1123
1124 // Reset the database manager so it picks up the replacement protocol manager.
1125 ResetLocalDatabaseManager();
1126 WaitForTasksOnTaskRunner();
1127
1128 std::string url_bad_no_scheme("example.com/bad/");
1129 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
1130 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
1131 StoreAndHashPrefixes store_and_hash_prefixes;
1132 store_and_hash_prefixes.emplace_back(GetChromeUrlClientIncidentId(),
1133 bad_hash_prefix);
1134 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1135
1136 const GURL url_bad("https://" + url_bad_no_scheme);
1137 TestClient client(SB_THREAT_TYPE_SAFE, url_bad);
1138 EXPECT_FALSE(v4_local_database_manager_->CheckResourceUrl(url_bad, &client));
1139 EXPECT_FALSE(client.on_check_resource_url_result_called());
1140 WaitForTasksOnTaskRunner();
1141 EXPECT_TRUE(client.on_check_resource_url_result_called());
1142 }
1143
TEST_F(V4LocalDatabaseManagerTest,TestSubresourceFilterCallback)1144 TEST_F(V4LocalDatabaseManagerTest, TestSubresourceFilterCallback) {
1145 // Setup to receive full-hash misses.
1146 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
1147
1148 // Reset the database manager so it picks up the replacement protocol manager.
1149 ResetLocalDatabaseManager();
1150 WaitForTasksOnTaskRunner();
1151
1152 std::string url_bad_no_scheme("example.com/bad/");
1153 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
1154 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
1155
1156 // Put a match in the db that will cause a protocol-manager request.
1157 StoreAndHashPrefixes store_and_hash_prefixes;
1158 store_and_hash_prefixes.emplace_back(GetUrlSubresourceFilterId(),
1159 bad_hash_prefix);
1160 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1161
1162 const GURL url_bad("https://" + url_bad_no_scheme);
1163 // Test that a request flows through to the callback.
1164 {
1165 TestClient client(SB_THREAT_TYPE_SAFE, url_bad);
1166 EXPECT_FALSE(v4_local_database_manager_->CheckUrlForSubresourceFilter(
1167 url_bad, &client));
1168 EXPECT_FALSE(client.on_check_browse_url_result_called());
1169 WaitForTasksOnTaskRunner();
1170 EXPECT_TRUE(client.on_check_browse_url_result_called());
1171 }
1172 }
1173
TEST_F(V4LocalDatabaseManagerTest,TestCheckResourceUrlReturnsBad)1174 TEST_F(V4LocalDatabaseManagerTest, TestCheckResourceUrlReturnsBad) {
1175 // Setup to receive full-hash hit.
1176 std::string url_bad_no_scheme("example.com/bad/");
1177 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
1178 FullHashInfo fhi(bad_full_hash, GetChromeUrlClientIncidentId(), base::Time());
1179 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({fhi}));
1180
1181 // Reset the database manager so it picks up the replacement protocol manager.
1182 ResetLocalDatabaseManager();
1183 WaitForTasksOnTaskRunner();
1184
1185 // Put a match in the db that will cause a protocol-manager request.
1186 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
1187 StoreAndHashPrefixes store_and_hash_prefixes;
1188 store_and_hash_prefixes.emplace_back(GetChromeUrlClientIncidentId(),
1189 bad_hash_prefix);
1190 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1191
1192 const GURL url_bad("https://" + url_bad_no_scheme);
1193 TestClient client(SB_THREAT_TYPE_BLACKLISTED_RESOURCE, url_bad);
1194 EXPECT_FALSE(v4_local_database_manager_->CheckResourceUrl(url_bad, &client));
1195 EXPECT_FALSE(client.on_check_resource_url_result_called());
1196 WaitForTasksOnTaskRunner();
1197 EXPECT_TRUE(client.on_check_resource_url_result_called());
1198 }
1199
TEST_F(V4LocalDatabaseManagerTest,TestCheckExtensionIDsNothingBlacklisted)1200 TEST_F(V4LocalDatabaseManagerTest, TestCheckExtensionIDsNothingBlacklisted) {
1201 // Setup to receive full-hash misses.
1202 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
1203
1204 // Reset the database manager so it picks up the replacement protocol manager.
1205 ResetLocalDatabaseManager();
1206 WaitForTasksOnTaskRunner();
1207
1208 // bad_extension_id is in the local DB but the full hash won't match.
1209 const FullHash bad_extension_id("aaaabbbbccccdddd"),
1210 good_extension_id("ddddccccbbbbaaaa");
1211
1212 // Put a match in the db that will cause a protocol-manager request.
1213 StoreAndHashPrefixes store_and_hash_prefixes;
1214 store_and_hash_prefixes.emplace_back(GetChromeExtMalwareId(),
1215 bad_extension_id);
1216 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1217
1218 const std::set<FullHash> expected_bad_crxs({});
1219 const std::set<FullHash> extension_ids({good_extension_id, bad_extension_id});
1220 TestExtensionClient client(expected_bad_crxs);
1221 EXPECT_FALSE(
1222 v4_local_database_manager_->CheckExtensionIDs(extension_ids, &client));
1223 EXPECT_FALSE(client.on_check_extensions_result_called());
1224 WaitForTasksOnTaskRunner();
1225 EXPECT_TRUE(client.on_check_extensions_result_called());
1226 }
1227
TEST_F(V4LocalDatabaseManagerTest,TestCheckExtensionIDsOneIsBlacklisted)1228 TEST_F(V4LocalDatabaseManagerTest, TestCheckExtensionIDsOneIsBlacklisted) {
1229 // bad_extension_id is in the local DB and the full hash will match.
1230 const FullHash bad_extension_id("aaaabbbbccccdddd"),
1231 good_extension_id("ddddccccbbbbaaaa");
1232 FullHashInfo fhi(bad_extension_id, GetChromeExtMalwareId(), base::Time());
1233
1234 // Setup to receive full-hash hit.
1235 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({fhi}));
1236
1237 // Reset the database manager so it picks up the replacement protocol manager.
1238 ResetLocalDatabaseManager();
1239 WaitForTasksOnTaskRunner();
1240
1241 // Put a match in the db that will cause a protocol-manager request.
1242 StoreAndHashPrefixes store_and_hash_prefixes;
1243 store_and_hash_prefixes.emplace_back(GetChromeExtMalwareId(),
1244 bad_extension_id);
1245 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1246
1247 const std::set<FullHash> expected_bad_crxs({bad_extension_id});
1248 const std::set<FullHash> extension_ids({good_extension_id, bad_extension_id});
1249 TestExtensionClient client(expected_bad_crxs);
1250 EXPECT_FALSE(
1251 v4_local_database_manager_->CheckExtensionIDs(extension_ids, &client));
1252 EXPECT_FALSE(client.on_check_extensions_result_called());
1253 WaitForTasksOnTaskRunner();
1254 EXPECT_TRUE(client.on_check_extensions_result_called());
1255 }
1256
TEST_F(V4LocalDatabaseManagerTest,TestCheckDownloadUrlNothingBlacklisted)1257 TEST_F(V4LocalDatabaseManagerTest, TestCheckDownloadUrlNothingBlacklisted) {
1258 // Setup to receive full-hash misses.
1259 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({}));
1260
1261 // Reset the database manager so it picks up the replacement protocol manager.
1262 ResetLocalDatabaseManager();
1263 WaitForTasksOnTaskRunner();
1264
1265 // Put a match in the db that will cause a protocol-manager request.
1266 std::string url_bad_no_scheme("example.com/bad/");
1267 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
1268 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
1269 StoreAndHashPrefixes store_and_hash_prefixes;
1270 store_and_hash_prefixes.emplace_back(GetUrlMalBinId(), bad_hash_prefix);
1271 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1272
1273 const GURL url_bad("https://" + url_bad_no_scheme),
1274 url_good("https://example.com/good/");
1275 const std::vector<GURL> url_chain({url_good, url_bad});
1276
1277 TestClient client(SB_THREAT_TYPE_SAFE, url_chain);
1278 EXPECT_FALSE(
1279 v4_local_database_manager_->CheckDownloadUrl(url_chain, &client));
1280 EXPECT_FALSE(client.on_check_download_urls_result_called());
1281 WaitForTasksOnTaskRunner();
1282 EXPECT_TRUE(client.on_check_download_urls_result_called());
1283 }
1284
TEST_F(V4LocalDatabaseManagerTest,TestCheckDownloadUrlWithOneBlacklisted)1285 TEST_F(V4LocalDatabaseManagerTest, TestCheckDownloadUrlWithOneBlacklisted) {
1286 // Setup to receive full-hash hit.
1287 std::string url_bad_no_scheme("example.com/bad/");
1288 FullHash bad_full_hash(crypto::SHA256HashString(url_bad_no_scheme));
1289 FullHashInfo fhi(bad_full_hash, GetUrlMalBinId(), base::Time());
1290 ScopedFakeGetHashProtocolManagerFactory pin(FullHashInfos({fhi}));
1291
1292 // Reset the database manager so it picks up the replacement protocol manager.
1293 ResetLocalDatabaseManager();
1294 WaitForTasksOnTaskRunner();
1295
1296 const GURL url_bad("https://" + url_bad_no_scheme),
1297 url_good("https://example.com/good/");
1298 const std::vector<GURL> url_chain({url_good, url_bad});
1299
1300 // Put a match in the db that will cause a protocol-manager request.
1301 const HashPrefix bad_hash_prefix(bad_full_hash.substr(0, 5));
1302 StoreAndHashPrefixes store_and_hash_prefixes;
1303 store_and_hash_prefixes.emplace_back(GetUrlMalBinId(), bad_hash_prefix);
1304 ReplaceV4Database(store_and_hash_prefixes, /* stores_available= */ true);
1305
1306 TestClient client(SB_THREAT_TYPE_URL_BINARY_MALWARE, url_chain);
1307 EXPECT_FALSE(
1308 v4_local_database_manager_->CheckDownloadUrl(url_chain, &client));
1309 EXPECT_FALSE(client.on_check_download_urls_result_called());
1310 WaitForTasksOnTaskRunner();
1311 EXPECT_TRUE(client.on_check_download_urls_result_called());
1312 }
1313
TEST_F(V4LocalDatabaseManagerTest,NotificationOnUpdate)1314 TEST_F(V4LocalDatabaseManagerTest, NotificationOnUpdate) {
1315 base::RunLoop run_loop;
1316 auto callback_subscription =
1317 v4_local_database_manager_->RegisterDatabaseUpdatedCallback(
1318 run_loop.QuitClosure());
1319
1320 // Creates and associates a V4Database instance.
1321 StoreAndHashPrefixes store_and_hash_prefixes;
1322 ReplaceV4Database(store_and_hash_prefixes);
1323
1324 v4_local_database_manager_->DatabaseUpdated();
1325
1326 run_loop.Run();
1327 }
1328
TEST_F(V4LocalDatabaseManagerTest,FlagOneUrlAsPhishing)1329 TEST_F(V4LocalDatabaseManagerTest, FlagOneUrlAsPhishing) {
1330 SetupFakeManager();
1331 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1332 "mark_as_phishing", "https://example.com/1/");
1333 PopulateArtificialDatabase();
1334
1335 const GURL url_bad("https://example.com/1/");
1336 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1337 url_bad, usual_threat_types_, nullptr));
1338 // PerformFullHashCheck will not be called if there is a match within the
1339 // artificial database
1340 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1341 v4_local_database_manager_));
1342
1343 const GURL url_good("https://other.example.com");
1344 EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
1345 url_good, usual_threat_types_, nullptr));
1346
1347 StopLocalDatabaseManager();
1348 }
1349
TEST_F(V4LocalDatabaseManagerTest,FlagOneUrlAsMalware)1350 TEST_F(V4LocalDatabaseManagerTest, FlagOneUrlAsMalware) {
1351 SetupFakeManager();
1352 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1353 "mark_as_malware", "https://example.com/1/");
1354 PopulateArtificialDatabase();
1355
1356 const GURL url_bad("https://example.com/1/");
1357 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1358 url_bad, usual_threat_types_, nullptr));
1359 // PerformFullHashCheck will not be called if there is a match within the
1360 // artificial database
1361 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1362 v4_local_database_manager_));
1363
1364 const GURL url_good("https://other.example.com");
1365 EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
1366 url_good, usual_threat_types_, nullptr));
1367
1368 StopLocalDatabaseManager();
1369 }
1370
TEST_F(V4LocalDatabaseManagerTest,FlagOneUrlAsUWS)1371 TEST_F(V4LocalDatabaseManagerTest, FlagOneUrlAsUWS) {
1372 SetupFakeManager();
1373 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1374 "mark_as_uws", "https://example.com/1/");
1375 PopulateArtificialDatabase();
1376
1377 const GURL url_bad("https://example.com/1/");
1378 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1379 url_bad, usual_threat_types_, nullptr));
1380 // PerformFullHashCheck will not be called if there is a match within the
1381 // artificial database
1382 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1383 v4_local_database_manager_));
1384
1385 const GURL url_good("https://other.example.com");
1386 EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
1387 url_good, usual_threat_types_, nullptr));
1388
1389 StopLocalDatabaseManager();
1390 }
1391
TEST_F(V4LocalDatabaseManagerTest,FlagMultipleUrls)1392 TEST_F(V4LocalDatabaseManagerTest, FlagMultipleUrls) {
1393 SetupFakeManager();
1394 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1395 "mark_as_phishing", "https://example.com/1/");
1396 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1397 "mark_as_malware", "https://2.example.com");
1398 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1399 "mark_as_uws", "https://example.test.com");
1400 PopulateArtificialDatabase();
1401
1402 const GURL url_phishing("https://example.com/1/");
1403 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1404 url_phishing, usual_threat_types_, nullptr));
1405 const GURL url_malware("https://2.example.com");
1406 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1407 url_malware, usual_threat_types_, nullptr));
1408 const GURL url_uws("https://example.test.com");
1409 EXPECT_FALSE(v4_local_database_manager_->CheckBrowseUrl(
1410 url_uws, usual_threat_types_, nullptr));
1411 // PerformFullHashCheck will not be called if there is a match within the
1412 // artificial database
1413 EXPECT_FALSE(FakeV4LocalDatabaseManager::PerformFullHashCheckCalled(
1414 v4_local_database_manager_));
1415
1416 const GURL url_good("https://other.example.com");
1417 EXPECT_TRUE(v4_local_database_manager_->CheckBrowseUrl(
1418 url_good, usual_threat_types_, nullptr));
1419
1420 StopLocalDatabaseManager();
1421 }
1422
1423 } // namespace safe_browsing
1424