1 // Copyright (c) 2012 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 // This test creates a safebrowsing service using test safebrowsing database 6 // and a test protocol manager. It is used to test logics in safebrowsing 7 // service. 8 9 #include <algorithm> 10 11 #include "base/bind.h" 12 #include "base/command_line.h" 13 #include "base/files/file_path.h" 14 #include "base/files/scoped_temp_dir.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/metrics/field_trial.h" 17 #include "base/path_service.h" 18 #include "base/prefs/pref_service.h" 19 #include "base/strings/string_split.h" 20 #include "base/test/thread_test_helper.h" 21 #include "base/time/time.h" 22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/prerender/prerender_manager.h" 25 #include "chrome/browser/profiles/profile.h" 26 #include "chrome/browser/profiles/profile_manager.h" 27 #include "chrome/browser/profiles/startup_task_runner_service.h" 28 #include "chrome/browser/profiles/startup_task_runner_service_factory.h" 29 #include "chrome/browser/safe_browsing/client_side_detection_service.h" 30 #include "chrome/browser/safe_browsing/database_manager.h" 31 #include "chrome/browser/safe_browsing/protocol_manager.h" 32 #include "chrome/browser/safe_browsing/safe_browsing_database.h" 33 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 34 #include "chrome/browser/safe_browsing/safe_browsing_util.h" 35 #include "chrome/browser/safe_browsing/ui_manager.h" 36 #include "chrome/browser/ui/browser.h" 37 #include "chrome/browser/ui/tabs/tab_strip_model.h" 38 #include "chrome/common/chrome_paths.h" 39 #include "chrome/common/chrome_switches.h" 40 #include "chrome/common/pref_names.h" 41 #include "chrome/test/base/in_process_browser_test.h" 42 #include "chrome/test/base/ui_test_utils.h" 43 #include "content/public/browser/web_contents.h" 44 #include "net/cookies/cookie_store.h" 45 #include "sql/connection.h" 46 #include "sql/statement.h" 47 #include "testing/gmock/include/gmock/gmock.h" 48 49 #if defined(OS_CHROMEOS) 50 #include "chromeos/chromeos_switches.h" 51 #endif 52 53 using content::BrowserThread; 54 using content::InterstitialPage; 55 using content::WebContents; 56 using ::testing::_; 57 using ::testing::Mock; 58 using ::testing::StrictMock; 59 60 namespace { 61 62 void InvokeFullHashCallback( 63 SafeBrowsingProtocolManager::FullHashCallback callback, 64 const std::vector<SBFullHashResult>& result) { 65 callback.Run(result, base::TimeDelta::FromMinutes(45)); 66 } 67 68 class FakeSafeBrowsingService : public SafeBrowsingService { 69 public: 70 explicit FakeSafeBrowsingService(const std::string& url_prefix) 71 : url_prefix_(url_prefix) {} 72 73 virtual SafeBrowsingProtocolConfig GetProtocolConfig() const OVERRIDE { 74 SafeBrowsingProtocolConfig config; 75 config.url_prefix = url_prefix_; 76 // Makes sure the auto update is not triggered. The tests will force the 77 // update when needed. 78 config.disable_auto_update = true; 79 config.client_name = "browser_tests"; 80 return config; 81 } 82 83 private: 84 virtual ~FakeSafeBrowsingService() {} 85 86 std::string url_prefix_; 87 88 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService); 89 }; 90 91 // Factory that creates FakeSafeBrowsingService instances. 92 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory { 93 public: 94 explicit TestSafeBrowsingServiceFactory(const std::string& url_prefix) 95 : url_prefix_(url_prefix) {} 96 97 virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE { 98 return new FakeSafeBrowsingService(url_prefix_); 99 } 100 101 private: 102 std::string url_prefix_; 103 }; 104 105 // A SafeBrowingDatabase class that allows us to inject the malicious URLs. 106 class TestSafeBrowsingDatabase : public SafeBrowsingDatabase { 107 public: 108 TestSafeBrowsingDatabase() {} 109 110 virtual ~TestSafeBrowsingDatabase() {} 111 112 // Initializes the database with the given filename. 113 virtual void Init(const base::FilePath& filename) OVERRIDE {} 114 115 // Deletes the current database and creates a new one. 116 virtual bool ResetDatabase() OVERRIDE { 117 badurls_.clear(); 118 return true; 119 } 120 121 // Called on the IO thread to check if the given URL is safe or not. If we 122 // can synchronously determine that the URL is safe, CheckUrl returns true, 123 // otherwise it returns false. 124 virtual bool ContainsBrowseUrl( 125 const GURL& url, 126 std::vector<SBPrefix>* prefix_hits, 127 std::vector<SBFullHashResult>* cache_hits) OVERRIDE { 128 cache_hits->clear(); 129 return ContainsUrl(safe_browsing_util::MALWARE, 130 safe_browsing_util::PHISH, 131 std::vector<GURL>(1, url), 132 prefix_hits); 133 } 134 virtual bool ContainsDownloadUrl( 135 const std::vector<GURL>& urls, 136 std::vector<SBPrefix>* prefix_hits) OVERRIDE { 137 bool found = ContainsUrl(safe_browsing_util::BINURL, 138 safe_browsing_util::BINURL, 139 urls, 140 prefix_hits); 141 if (!found) 142 return false; 143 DCHECK_LE(1U, prefix_hits->size()); 144 return true; 145 } 146 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) OVERRIDE { 147 return true; 148 } 149 virtual bool ContainsDownloadWhitelistedString( 150 const std::string& str) OVERRIDE { 151 return true; 152 } 153 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) OVERRIDE { 154 return true; 155 } 156 virtual bool ContainsExtensionPrefixes( 157 const std::vector<SBPrefix>& prefixes, 158 std::vector<SBPrefix>* prefix_hits) OVERRIDE { 159 return true; 160 } 161 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) OVERRIDE { 162 return true; 163 } 164 virtual bool ContainsMalwareIP(const std::string& ip_address) OVERRIDE { 165 return true; 166 } 167 virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) OVERRIDE { 168 ADD_FAILURE() << "Not implemented."; 169 return false; 170 } 171 virtual void InsertChunks( 172 const std::string& list_name, 173 const std::vector<SBChunkData*>& chunks) OVERRIDE { 174 ADD_FAILURE() << "Not implemented."; 175 } 176 virtual void DeleteChunks( 177 const std::vector<SBChunkDelete>& chunk_deletes) OVERRIDE { 178 ADD_FAILURE() << "Not implemented."; 179 } 180 virtual void UpdateFinished(bool update_succeeded) OVERRIDE { 181 ADD_FAILURE() << "Not implemented."; 182 } 183 virtual void CacheHashResults( 184 const std::vector<SBPrefix>& prefixes, 185 const std::vector<SBFullHashResult>& cache_hits, 186 const base::TimeDelta& cache_lifetime) OVERRIDE { 187 // Do nothing for the cache. 188 } 189 virtual bool IsMalwareIPMatchKillSwitchOn() OVERRIDE { 190 return false; 191 } 192 virtual bool IsCsdWhitelistKillSwitchOn() OVERRIDE { 193 return false; 194 } 195 196 // Fill up the database with test URL. 197 void AddUrl(const GURL& url, 198 int list_id, 199 const std::vector<SBPrefix>& prefix_hits) { 200 badurls_[url.spec()].list_id = list_id; 201 badurls_[url.spec()].prefix_hits = prefix_hits; 202 } 203 204 // Fill up the database with test hash digest. 205 void AddDownloadPrefix(SBPrefix prefix) { 206 download_digest_prefix_.insert(prefix); 207 } 208 209 private: 210 struct Hits { 211 int list_id; 212 std::vector<SBPrefix> prefix_hits; 213 }; 214 215 bool ContainsUrl(int list_id0, 216 int list_id1, 217 const std::vector<GURL>& urls, 218 std::vector<SBPrefix>* prefix_hits) { 219 bool hit = false; 220 for (size_t i = 0; i < urls.size(); ++i) { 221 const GURL& url = urls[i]; 222 base::hash_map<std::string, Hits>::const_iterator 223 badurls_it = badurls_.find(url.spec()); 224 225 if (badurls_it == badurls_.end()) 226 continue; 227 228 if (badurls_it->second.list_id == list_id0 || 229 badurls_it->second.list_id == list_id1) { 230 prefix_hits->insert(prefix_hits->end(), 231 badurls_it->second.prefix_hits.begin(), 232 badurls_it->second.prefix_hits.end()); 233 hit = true; 234 } 235 } 236 return hit; 237 } 238 239 base::hash_map<std::string, Hits> badurls_; 240 base::hash_set<SBPrefix> download_digest_prefix_; 241 }; 242 243 // Factory that creates TestSafeBrowsingDatabase instances. 244 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory { 245 public: 246 TestSafeBrowsingDatabaseFactory() : db_(NULL) {} 247 virtual ~TestSafeBrowsingDatabaseFactory() {} 248 249 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( 250 bool enable_download_protection, 251 bool enable_client_side_whitelist, 252 bool enable_download_whitelist, 253 bool enable_extension_blacklist, 254 bool enable_side_effect_free_whitelist, 255 bool enable_ip_blacklist) OVERRIDE { 256 db_ = new TestSafeBrowsingDatabase(); 257 return db_; 258 } 259 TestSafeBrowsingDatabase* GetDb() { 260 return db_; 261 } 262 private: 263 // Owned by the SafebrowsingService. 264 TestSafeBrowsingDatabase* db_; 265 }; 266 267 // A TestProtocolManager that could return fixed responses from 268 // safebrowsing server for testing purpose. 269 class TestProtocolManager : public SafeBrowsingProtocolManager { 270 public: 271 TestProtocolManager(SafeBrowsingProtocolManagerDelegate* delegate, 272 net::URLRequestContextGetter* request_context_getter, 273 const SafeBrowsingProtocolConfig& config) 274 : SafeBrowsingProtocolManager(delegate, request_context_getter, config) { 275 create_count_++; 276 } 277 278 virtual ~TestProtocolManager() { 279 delete_count_++; 280 } 281 282 // This function is called when there is a prefix hit in local safebrowsing 283 // database and safebrowsing service issues a get hash request to backends. 284 // We return a result from the prefilled full_hashes_ hash_map to simulate 285 // server's response. At the same time, latency is added to simulate real 286 // life network issues. 287 virtual void GetFullHash( 288 const std::vector<SBPrefix>& prefixes, 289 SafeBrowsingProtocolManager::FullHashCallback callback, 290 bool is_download) OVERRIDE { 291 BrowserThread::PostDelayedTask( 292 BrowserThread::IO, FROM_HERE, 293 base::Bind(InvokeFullHashCallback, callback, full_hashes_), 294 delay_); 295 } 296 297 // Prepare the GetFullHash results for the next request. 298 void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) { 299 full_hashes_.clear(); 300 full_hashes_.push_back(full_hash_result); 301 } 302 303 void IntroduceDelay(const base::TimeDelta& delay) { 304 delay_ = delay; 305 } 306 307 static int create_count() { 308 return create_count_; 309 } 310 311 static int delete_count() { 312 return delete_count_; 313 } 314 315 private: 316 std::vector<SBFullHashResult> full_hashes_; 317 base::TimeDelta delay_; 318 static int create_count_; 319 static int delete_count_; 320 }; 321 322 // static 323 int TestProtocolManager::create_count_ = 0; 324 // static 325 int TestProtocolManager::delete_count_ = 0; 326 327 // Factory that creates TestProtocolManager instances. 328 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory { 329 public: 330 TestSBProtocolManagerFactory() : pm_(NULL) {} 331 virtual ~TestSBProtocolManagerFactory() {} 332 333 virtual SafeBrowsingProtocolManager* CreateProtocolManager( 334 SafeBrowsingProtocolManagerDelegate* delegate, 335 net::URLRequestContextGetter* request_context_getter, 336 const SafeBrowsingProtocolConfig& config) OVERRIDE { 337 pm_ = new TestProtocolManager(delegate, request_context_getter, config); 338 return pm_; 339 } 340 341 TestProtocolManager* GetProtocolManager() { 342 return pm_; 343 } 344 345 private: 346 // Owned by the SafebrowsingService. 347 TestProtocolManager* pm_; 348 }; 349 350 class MockObserver : public SafeBrowsingUIManager::Observer { 351 public: 352 MockObserver() {} 353 virtual ~MockObserver() {} 354 MOCK_METHOD1(OnSafeBrowsingHit, 355 void(const SafeBrowsingUIManager::UnsafeResource&)); 356 MOCK_METHOD1(OnSafeBrowsingMatch, 357 void(const SafeBrowsingUIManager::UnsafeResource&)); 358 }; 359 360 MATCHER_P(IsUnsafeResourceFor, url, "") { 361 return (arg.url.spec() == url.spec() && 362 arg.threat_type != SB_THREAT_TYPE_SAFE); 363 } 364 365 } // namespace 366 367 // Tests the safe browsing blocking page in a browser. 368 class SafeBrowsingServiceTest : public InProcessBrowserTest { 369 public: 370 SafeBrowsingServiceTest() { 371 } 372 373 static void GenUrlFullhashResult(const GURL& url, 374 int list_id, 375 SBFullHashResult* full_hash) { 376 std::string host; 377 std::string path; 378 safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL); 379 full_hash->hash = SBFullHashForString(host + path); 380 full_hash->list_id = list_id; 381 } 382 383 virtual void SetUp() { 384 // InProcessBrowserTest::SetUp() instantiates SafebrowsingService and 385 // RegisterFactory has to be called before SafeBrowsingService is created. 386 sb_factory_.reset(new TestSafeBrowsingServiceFactory( 387 "https://definatelynotarealdomain/safebrowsing")); 388 SafeBrowsingService::RegisterFactory(sb_factory_.get()); 389 SafeBrowsingDatabase::RegisterFactory(&db_factory_); 390 SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_); 391 InProcessBrowserTest::SetUp(); 392 } 393 394 virtual void TearDown() { 395 InProcessBrowserTest::TearDown(); 396 397 // Unregister test factories after InProcessBrowserTest::TearDown 398 // (which destructs SafeBrowsingService). 399 SafeBrowsingDatabase::RegisterFactory(NULL); 400 SafeBrowsingProtocolManager::RegisterFactory(NULL); 401 SafeBrowsingService::RegisterFactory(NULL); 402 } 403 404 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 405 // Makes sure the auto update is not triggered during the test. 406 // This test will fill up the database using testing prefixes 407 // and urls. 408 command_line->AppendSwitch(switches::kSbDisableAutoUpdate); 409 #if defined(OS_CHROMEOS) 410 command_line->AppendSwitch( 411 chromeos::switches::kIgnoreUserProfileMappingForTests); 412 #endif 413 } 414 415 virtual void SetUpInProcessBrowserTestFixture() { 416 ASSERT_TRUE(test_server()->Start()); 417 } 418 419 // This will setup the "url" prefix in database and prepare protocol manager 420 // to response with |full_hash| for get full hash request. 421 void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) { 422 std::vector<SBPrefix> prefix_hits; 423 prefix_hits.push_back(full_hash.hash.prefix); 424 425 // Make sure the full hits is empty unless we need to test the 426 // full hash is hit in database's local cache. 427 TestSafeBrowsingDatabase* db = db_factory_.GetDb(); 428 db->AddUrl(url, full_hash.list_id, prefix_hits); 429 430 TestProtocolManager* pm = pm_factory_.GetProtocolManager(); 431 pm->SetGetFullHashResponse(full_hash); 432 } 433 434 bool ShowingInterstitialPage() { 435 WebContents* contents = 436 browser()->tab_strip_model()->GetActiveWebContents(); 437 InterstitialPage* interstitial_page = contents->GetInterstitialPage(); 438 return interstitial_page != NULL; 439 } 440 441 void IntroduceGetHashDelay(const base::TimeDelta& delay) { 442 pm_factory_.GetProtocolManager()->IntroduceDelay(delay); 443 } 444 445 base::TimeDelta GetCheckTimeout(SafeBrowsingService* sb_service) { 446 return sb_service->database_manager()->check_timeout_; 447 } 448 449 void SetCheckTimeout(SafeBrowsingService* sb_service, 450 const base::TimeDelta& delay) { 451 sb_service->database_manager()->check_timeout_ = delay; 452 } 453 454 void CreateCSDService() { 455 safe_browsing::ClientSideDetectionService* csd_service = 456 safe_browsing::ClientSideDetectionService::Create(NULL); 457 SafeBrowsingService* sb_service = 458 g_browser_process->safe_browsing_service(); 459 sb_service->csd_service_.reset(csd_service); 460 sb_service->RefreshState(); 461 } 462 463 void ProceedAndWhitelist( 464 const SafeBrowsingUIManager::UnsafeResource& resource) { 465 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; 466 resources.push_back(resource); 467 BrowserThread::PostTask( 468 BrowserThread::IO, FROM_HERE, 469 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone, 470 g_browser_process->safe_browsing_service()->ui_manager(), 471 resources, true)); 472 WaitForIOThread(); 473 } 474 475 protected: 476 StrictMock<MockObserver> observer_; 477 478 // Temporary profile dir for test cases that create a second profile. This is 479 // owned by the SafeBrowsingServiceTest object so that it will not get 480 // destructed until after the test Browser has been torn down, since the 481 // ImportantFileWriter may still be modifying it after the Profile object has 482 // been destroyed. 483 base::ScopedTempDir temp_profile_dir_; 484 485 // Waits for pending tasks on the IO thread to complete. This is useful 486 // to wait for the SafeBrowsingService to finish loading/stopping. 487 void WaitForIOThread() { 488 scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper( 489 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())); 490 ASSERT_TRUE(io_helper->Run()); 491 } 492 493 private: 494 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_; 495 TestSafeBrowsingDatabaseFactory db_factory_; 496 TestSBProtocolManagerFactory pm_factory_; 497 498 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest); 499 }; 500 501 namespace { 502 503 const char kEmptyPage[] = "files/empty.html"; 504 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe"; 505 const char kMalwarePage[] = "files/safe_browsing/malware.html"; 506 507 // This test goes through DownloadResourceHandler. 508 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) { 509 GURL url = test_server()->GetURL(kEmptyPage); 510 g_browser_process->safe_browsing_service()-> 511 ui_manager()->AddObserver(&observer_); 512 513 // After adding the url to safebrowsing database and getfullhash result, 514 // we should see the interstitial page. 515 SBFullHashResult malware_full_hash; 516 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash); 517 EXPECT_CALL(observer_, 518 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1); 519 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1); 520 SetupResponseForUrl(url, malware_full_hash); 521 ui_test_utils::NavigateToURL(browser(), url); 522 EXPECT_TRUE(ShowingInterstitialPage()); 523 g_browser_process->safe_browsing_service()-> 524 ui_manager()->RemoveObserver(&observer_); 525 } 526 527 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, DISABLED_MalwareWithWhitelist) { 528 GURL url = test_server()->GetURL(kEmptyPage); 529 g_browser_process->safe_browsing_service()-> 530 ui_manager()->AddObserver(&observer_); 531 532 // After adding the url to safebrowsing database and getfullhash result, 533 // we should see the interstitial page. 534 SBFullHashResult malware_full_hash; 535 GenUrlFullhashResult(url, safe_browsing_util::MALWARE, &malware_full_hash); 536 EXPECT_CALL(observer_, 537 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1); 538 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1) 539 .WillOnce(testing::Invoke( 540 this, &SafeBrowsingServiceTest::ProceedAndWhitelist)); 541 SetupResponseForUrl(url, malware_full_hash); 542 543 ui_test_utils::NavigateToURL(browser(), url); 544 // Mock calls OnBlockingPageDone set to proceed, so the interstitial 545 // is removed. 546 EXPECT_FALSE(ShowingInterstitialPage()); 547 Mock::VerifyAndClearExpectations(&observer_); 548 549 // Navigate back to kEmptyPage -- should hit the whitelist, and send a match 550 // call, but no hit call. 551 EXPECT_CALL(observer_, 552 OnSafeBrowsingMatch(IsUnsafeResourceFor(url))).Times(1); 553 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(0); 554 ui_test_utils::NavigateToURL(browser(), url); 555 EXPECT_FALSE(ShowingInterstitialPage()); 556 557 g_browser_process->safe_browsing_service()-> 558 ui_manager()->RemoveObserver(&observer_); 559 } 560 561 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html"; 562 563 // This test confirms that prefetches don't themselves get the 564 // interstitial treatment. 565 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) { 566 GURL url = test_server()->GetURL(kPrefetchMalwarePage); 567 GURL malware_url = test_server()->GetURL(kMalwarePage); 568 g_browser_process->safe_browsing_service()-> 569 ui_manager()->AddObserver(&observer_); 570 571 class SetPrefetchForTest { 572 public: 573 explicit SetPrefetchForTest(bool prefetch) 574 : old_prerender_mode_(prerender::PrerenderManager::GetMode()) { 575 std::string exp_group = prefetch ? "ExperimentYes" : "ExperimentNo"; 576 base::FieldTrialList::CreateFieldTrial("Prefetch", exp_group); 577 578 prerender::PrerenderManager::SetMode( 579 prerender::PrerenderManager::PRERENDER_MODE_DISABLED); 580 } 581 582 ~SetPrefetchForTest() { 583 prerender::PrerenderManager::SetMode(old_prerender_mode_); 584 } 585 586 private: 587 prerender::PrerenderManager::PrerenderManagerMode old_prerender_mode_; 588 } set_prefetch_for_test(true); 589 590 // Even though we have added this uri to the safebrowsing database and 591 // getfullhash result, we should not see the interstitial page since the 592 // only malware was a prefetch target. 593 SBFullHashResult malware_full_hash; 594 GenUrlFullhashResult(malware_url, safe_browsing_util::MALWARE, 595 &malware_full_hash); 596 SetupResponseForUrl(malware_url, malware_full_hash); 597 ui_test_utils::NavigateToURL(browser(), url); 598 EXPECT_FALSE(ShowingInterstitialPage()); 599 Mock::VerifyAndClear(&observer_); 600 601 // However, when we navigate to the malware page, we should still get 602 // the interstitial. 603 EXPECT_CALL(observer_, OnSafeBrowsingMatch(IsUnsafeResourceFor(malware_url))) 604 .Times(1); 605 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url))) 606 .Times(1); 607 ui_test_utils::NavigateToURL(browser(), malware_url); 608 EXPECT_TRUE(ShowingInterstitialPage()); 609 Mock::VerifyAndClear(&observer_); 610 g_browser_process->safe_browsing_service()-> 611 ui_manager()->RemoveObserver(&observer_); 612 } 613 614 } // namespace 615 616 class TestSBClient 617 : public base::RefCountedThreadSafe<TestSBClient>, 618 public SafeBrowsingDatabaseManager::Client { 619 public: 620 TestSBClient() 621 : threat_type_(SB_THREAT_TYPE_SAFE), 622 safe_browsing_service_(g_browser_process->safe_browsing_service()) { 623 } 624 625 SBThreatType GetThreatType() const { 626 return threat_type_; 627 } 628 629 void CheckDownloadUrl(const std::vector<GURL>& url_chain) { 630 BrowserThread::PostTask( 631 BrowserThread::IO, FROM_HERE, 632 base::Bind(&TestSBClient::CheckDownloadUrlOnIOThread, 633 this, url_chain)); 634 content::RunMessageLoop(); // Will stop in OnCheckDownloadUrlResult. 635 } 636 637 private: 638 friend class base::RefCountedThreadSafe<TestSBClient>; 639 virtual ~TestSBClient() {} 640 641 void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) { 642 safe_browsing_service_->database_manager()-> 643 CheckDownloadUrl(url_chain, this); 644 } 645 646 // Called when the result of checking a download URL is known. 647 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain, 648 SBThreatType threat_type) OVERRIDE { 649 threat_type_ = threat_type; 650 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 651 base::Bind(&TestSBClient::DownloadCheckDone, this)); 652 } 653 654 void DownloadCheckDone() { 655 base::MessageLoopForUI::current()->Quit(); 656 } 657 658 SBThreatType threat_type_; 659 SafeBrowsingService* safe_browsing_service_; 660 661 DISALLOW_COPY_AND_ASSIGN(TestSBClient); 662 }; 663 664 // These tests use SafeBrowsingService::Client to directly interact with 665 // SafeBrowsingService. 666 namespace { 667 668 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) { 669 GURL badbin_url = test_server()->GetURL(kMalwareFile); 670 std::vector<GURL> badbin_urls(1, badbin_url); 671 672 scoped_refptr<TestSBClient> client(new TestSBClient); 673 client->CheckDownloadUrl(badbin_urls); 674 675 // Since badbin_url is not in database, it is considered to be safe. 676 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType()); 677 678 SBFullHashResult full_hash_result; 679 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL, 680 &full_hash_result); 681 SetupResponseForUrl(badbin_url, full_hash_result); 682 683 client->CheckDownloadUrl(badbin_urls); 684 685 // Now, the badbin_url is not safe since it is added to download database. 686 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType()); 687 } 688 689 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) { 690 GURL original_url = test_server()->GetURL(kEmptyPage); 691 GURL badbin_url = test_server()->GetURL(kMalwareFile); 692 GURL final_url = test_server()->GetURL(kEmptyPage); 693 std::vector<GURL> badbin_urls; 694 badbin_urls.push_back(original_url); 695 badbin_urls.push_back(badbin_url); 696 badbin_urls.push_back(final_url); 697 698 scoped_refptr<TestSBClient> client(new TestSBClient); 699 client->CheckDownloadUrl(badbin_urls); 700 701 // Since badbin_url is not in database, it is considered to be safe. 702 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType()); 703 704 SBFullHashResult full_hash_result; 705 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL, 706 &full_hash_result); 707 SetupResponseForUrl(badbin_url, full_hash_result); 708 709 client->CheckDownloadUrl(badbin_urls); 710 711 // Now, the badbin_url is not safe since it is added to download database. 712 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType()); 713 } 714 715 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlTimedOut) { 716 GURL badbin_url = test_server()->GetURL(kMalwareFile); 717 std::vector<GURL> badbin_urls(1, badbin_url); 718 719 scoped_refptr<TestSBClient> client(new TestSBClient); 720 SBFullHashResult full_hash_result; 721 GenUrlFullhashResult(badbin_url, safe_browsing_util::BINURL, 722 &full_hash_result); 723 SetupResponseForUrl(badbin_url, full_hash_result); 724 client->CheckDownloadUrl(badbin_urls); 725 726 // badbin_url is not safe since it is added to download database. 727 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType()); 728 729 // 730 // Now introducing delays and we should hit timeout. 731 // 732 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); 733 base::TimeDelta default_urlcheck_timeout = GetCheckTimeout(sb_service); 734 IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1)); 735 SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1)); 736 client->CheckDownloadUrl(badbin_urls); 737 738 // There should be a timeout and the hash would be considered as safe. 739 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType()); 740 741 // Need to set the timeout back to the default value. 742 SetCheckTimeout(sb_service, default_urlcheck_timeout); 743 } 744 745 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) { 746 CreateCSDService(); 747 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); 748 safe_browsing::ClientSideDetectionService* csd_service = 749 sb_service->safe_browsing_detection_service(); 750 PrefService* pref_service = browser()->profile()->GetPrefs(); 751 752 ASSERT_TRUE(sb_service != NULL); 753 ASSERT_TRUE(csd_service != NULL); 754 ASSERT_TRUE(pref_service != NULL); 755 756 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled)); 757 758 // SBS might still be starting, make sure this doesn't flake. 759 WaitForIOThread(); 760 EXPECT_TRUE(sb_service->enabled()); 761 EXPECT_TRUE(csd_service->enabled()); 762 763 // Add a new Profile. SBS should keep running. 764 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); 765 scoped_ptr<Profile> profile2(Profile::CreateProfile( 766 temp_profile_dir_.path(), NULL, Profile::CREATE_MODE_SYNCHRONOUS)); 767 ASSERT_TRUE(profile2.get() != NULL); 768 StartupTaskRunnerServiceFactory::GetForProfile(profile2.get())-> 769 StartDeferredTaskRunners(); 770 PrefService* pref_service2 = profile2->GetPrefs(); 771 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled)); 772 // We don't expect the state to have changed, but if it did, wait for it. 773 WaitForIOThread(); 774 EXPECT_TRUE(sb_service->enabled()); 775 EXPECT_TRUE(csd_service->enabled()); 776 777 // Change one of the prefs. SBS should keep running. 778 pref_service->SetBoolean(prefs::kSafeBrowsingEnabled, false); 779 WaitForIOThread(); 780 EXPECT_TRUE(sb_service->enabled()); 781 EXPECT_TRUE(csd_service->enabled()); 782 783 // Change the other pref. SBS should stop now. 784 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, false); 785 WaitForIOThread(); 786 EXPECT_FALSE(sb_service->enabled()); 787 EXPECT_FALSE(csd_service->enabled()); 788 789 // Turn it back on. SBS comes back. 790 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, true); 791 WaitForIOThread(); 792 EXPECT_TRUE(sb_service->enabled()); 793 EXPECT_TRUE(csd_service->enabled()); 794 795 // Delete the Profile. SBS stops again. 796 pref_service2 = NULL; 797 profile2.reset(); 798 WaitForIOThread(); 799 EXPECT_FALSE(sb_service->enabled()); 800 EXPECT_FALSE(csd_service->enabled()); 801 } 802 803 } // namespace 804 805 class SafeBrowsingServiceShutdownTest : public SafeBrowsingServiceTest { 806 public: 807 virtual void TearDown() OVERRIDE { 808 // Browser should be fully torn down by now, so we can safely check these 809 // counters. 810 EXPECT_EQ(1, TestProtocolManager::create_count()); 811 EXPECT_EQ(1, TestProtocolManager::delete_count()); 812 813 SafeBrowsingServiceTest::TearDown(); 814 } 815 816 // An observer that returns back to test code after a new profile is 817 // initialized. 818 void OnUnblockOnProfileCreation(Profile* profile, 819 Profile::CreateStatus status) { 820 if (status == Profile::CREATE_STATUS_INITIALIZED) { 821 profile2_ = profile; 822 base::MessageLoop::current()->Quit(); 823 } 824 } 825 826 protected: 827 Profile* profile2_; 828 }; 829 830 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceShutdownTest, 831 DontStartAfterShutdown) { 832 CreateCSDService(); 833 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); 834 safe_browsing::ClientSideDetectionService* csd_service = 835 sb_service->safe_browsing_detection_service(); 836 PrefService* pref_service = browser()->profile()->GetPrefs(); 837 838 ASSERT_TRUE(sb_service != NULL); 839 ASSERT_TRUE(csd_service != NULL); 840 ASSERT_TRUE(pref_service != NULL); 841 842 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled)); 843 844 // SBS might still be starting, make sure this doesn't flake. 845 WaitForIOThread(); 846 EXPECT_EQ(1, TestProtocolManager::create_count()); 847 EXPECT_EQ(0, TestProtocolManager::delete_count()); 848 849 // Create an additional profile. We need to use the ProfileManager so that 850 // the profile will get destroyed in the normal browser shutdown process. 851 ProfileManager* profile_manager = g_browser_process->profile_manager(); 852 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); 853 profile_manager->CreateProfileAsync( 854 temp_profile_dir_.path(), 855 base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation, 856 this), 857 base::string16(), base::string16(), std::string()); 858 859 // Spin to allow profile creation to take place, loop is terminated 860 // by OnUnblockOnProfileCreation when the profile is created. 861 content::RunMessageLoop(); 862 863 PrefService* pref_service2 = profile2_->GetPrefs(); 864 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled)); 865 866 // We don't expect the state to have changed, but if it did, wait for it. 867 WaitForIOThread(); 868 EXPECT_EQ(1, TestProtocolManager::create_count()); 869 EXPECT_EQ(0, TestProtocolManager::delete_count()); 870 871 // End the test, shutting down the browser. 872 // SafeBrowsingServiceShutdownTest::TearDown will check the create_count and 873 // delete_count again. 874 } 875 876 class SafeBrowsingDatabaseManagerCookieTest : public InProcessBrowserTest { 877 public: 878 SafeBrowsingDatabaseManagerCookieTest() {} 879 880 virtual void SetUp() OVERRIDE { 881 // We need to start the test server to get the host&port in the url. 882 ASSERT_TRUE(test_server()->Start()); 883 884 // Point to the testing server for all SafeBrowsing requests. 885 GURL url_prefix = test_server()->GetURL( 886 "expect-and-set-cookie?expect=a%3db" 887 "&set=c%3dd%3b%20Expires=Fri,%2001%20Jan%202038%2001:01:01%20GMT" 888 "&data=foo#"); 889 sb_factory_.reset(new TestSafeBrowsingServiceFactory(url_prefix.spec())); 890 SafeBrowsingService::RegisterFactory(sb_factory_.get()); 891 892 InProcessBrowserTest::SetUp(); 893 } 894 895 virtual void TearDown() OVERRIDE { 896 InProcessBrowserTest::TearDown(); 897 898 SafeBrowsingService::RegisterFactory(NULL); 899 } 900 901 virtual bool SetUpUserDataDirectory() OVERRIDE { 902 base::FilePath cookie_path( 903 SafeBrowsingService::GetCookieFilePathForTesting()); 904 EXPECT_FALSE(base::PathExists(cookie_path)); 905 906 base::FilePath test_dir; 907 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) { 908 EXPECT_TRUE(false); 909 return false; 910 } 911 912 // Initialize the SafeBrowsing cookies with a pre-created cookie store. It 913 // contains a single cookie, for domain 127.0.0.1, with value a=b, and 914 // expires in 2038. 915 base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing") 916 .AppendASCII("Safe Browsing Cookies"); 917 if (!base::CopyFile(initial_cookies, cookie_path)) { 918 EXPECT_TRUE(false); 919 return false; 920 } 921 922 sql::Connection db; 923 if (!db.Open(cookie_path)) { 924 EXPECT_TRUE(false); 925 return false; 926 } 927 // Ensure the host value in the cookie file matches the test server we will 928 // be connecting to. 929 sql::Statement smt(db.GetUniqueStatement( 930 "UPDATE cookies SET host_key = ?")); 931 if (!smt.is_valid()) { 932 EXPECT_TRUE(false); 933 return false; 934 } 935 if (!smt.BindString(0, test_server()->host_port_pair().host())) { 936 EXPECT_TRUE(false); 937 return false; 938 } 939 if (!smt.Run()) { 940 EXPECT_TRUE(false); 941 return false; 942 } 943 944 return InProcessBrowserTest::SetUpUserDataDirectory(); 945 } 946 947 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { 948 InProcessBrowserTest::TearDownInProcessBrowserTestFixture(); 949 950 sql::Connection db; 951 base::FilePath cookie_path( 952 SafeBrowsingService::GetCookieFilePathForTesting()); 953 ASSERT_TRUE(db.Open(cookie_path)); 954 955 sql::Statement smt(db.GetUniqueStatement( 956 "SELECT name, value FROM cookies ORDER BY name")); 957 ASSERT_TRUE(smt.is_valid()); 958 959 ASSERT_TRUE(smt.Step()); 960 ASSERT_EQ("a", smt.ColumnString(0)); 961 ASSERT_EQ("b", smt.ColumnString(1)); 962 ASSERT_TRUE(smt.Step()); 963 ASSERT_EQ("c", smt.ColumnString(0)); 964 ASSERT_EQ("d", smt.ColumnString(1)); 965 EXPECT_FALSE(smt.Step()); 966 } 967 968 virtual void SetUpOnMainThread() OVERRIDE { 969 sb_service_ = g_browser_process->safe_browsing_service(); 970 ASSERT_TRUE(sb_service_.get() != NULL); 971 } 972 973 virtual void CleanUpOnMainThread() OVERRIDE { 974 sb_service_ = NULL; 975 } 976 977 void ForceUpdate() { 978 sb_service_->protocol_manager()->ForceScheduleNextUpdate( 979 base::TimeDelta::FromSeconds(0)); 980 } 981 982 scoped_refptr<SafeBrowsingService> sb_service_; 983 984 private: 985 scoped_ptr<TestSafeBrowsingServiceFactory> sb_factory_; 986 987 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManagerCookieTest); 988 }; 989 990 // Test that a Safe Browsing database update request both sends cookies and can 991 // save cookies. 992 IN_PROC_BROWSER_TEST_F(SafeBrowsingDatabaseManagerCookieTest, 993 TestSBUpdateCookies) { 994 content::WindowedNotificationObserver observer( 995 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE, 996 content::Source<SafeBrowsingDatabaseManager>( 997 sb_service_->database_manager().get())); 998 BrowserThread::PostTask( 999 BrowserThread::IO, 1000 FROM_HERE, 1001 base::Bind(&SafeBrowsingDatabaseManagerCookieTest::ForceUpdate, this)); 1002 observer.Wait(); 1003 } 1004