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