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