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.
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
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/path_service.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/strings/string_split.h"
19 #include "base/test/thread_test_helper.h"
20 #include "base/time/time.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/prerender/prerender_manager.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/browser/profiles/startup_task_runner_service.h"
27 #include "chrome/browser/profiles/startup_task_runner_service_factory.h"
28 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
29 #include "chrome/browser/safe_browsing/database_manager.h"
30 #include "chrome/browser/safe_browsing/protocol_manager.h"
31 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
32 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
33 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
34 #include "chrome/browser/safe_browsing/ui_manager.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/tabs/tab_strip_model.h"
37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/pref_names.h"
40 #include "chrome/test/base/in_process_browser_test.h"
41 #include "chrome/test/base/ui_test_utils.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/browser/web_contents_view.h"
44 #include "crypto/sha2.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"
50 using content::BrowserThread;
51 using content::InterstitialPage;
52 using content::WebContents;
54 using ::testing::Mock;
55 using ::testing::StrictMock;
59 void InvokeFullHashCallback(
60 SafeBrowsingProtocolManager::FullHashCallback callback,
61 const std::vector<SBFullHashResult>& result) {
62 callback.Run(result, true);
67 // A SafeBrowingDatabase class that allows us to inject the malicious URLs.
68 class TestSafeBrowsingDatabase : public SafeBrowsingDatabase {
70 TestSafeBrowsingDatabase() {}
72 virtual ~TestSafeBrowsingDatabase() {}
74 // Initializes the database with the given filename.
75 virtual void Init(const base::FilePath& filename) OVERRIDE {}
77 // Deletes the current database and creates a new one.
78 virtual bool ResetDatabase() OVERRIDE {
83 // Called on the IO thread to check if the given URL is safe or not. If we
84 // can synchronously determine that the URL is safe, CheckUrl returns true,
85 // otherwise it returns false.
86 virtual bool ContainsBrowseUrl(const GURL& url,
87 std::string* matching_list,
88 std::vector<SBPrefix>* prefix_hits,
89 std::vector<SBFullHashResult>* full_hits,
90 base::Time last_update) OVERRIDE {
91 std::vector<GURL> urls(1, url);
92 return ContainsUrl(safe_browsing_util::kMalwareList,
93 safe_browsing_util::kPhishingList,
94 urls, prefix_hits, full_hits);
96 virtual bool ContainsDownloadUrl(
97 const std::vector<GURL>& urls,
98 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
99 std::vector<SBFullHashResult> full_hits;
100 bool found = ContainsUrl(safe_browsing_util::kBinUrlList,
101 safe_browsing_util::kBinHashList,
102 urls, prefix_hits, &full_hits);
105 DCHECK_LE(1U, prefix_hits->size());
108 virtual bool ContainsDownloadHashPrefix(const SBPrefix& prefix) OVERRIDE {
109 return download_digest_prefix_.count(prefix) > 0;
111 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) OVERRIDE {
114 virtual bool ContainsDownloadWhitelistedString(
115 const std::string& str) OVERRIDE {
118 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) OVERRIDE {
121 virtual bool ContainsExtensionPrefixes(
122 const std::vector<SBPrefix>& prefixes,
123 std::vector<SBPrefix>* prefix_hits) OVERRIDE {
126 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) OVERRIDE {
129 virtual bool ContainsMalwareIP(const std::string& ip_address) OVERRIDE {
132 virtual bool UpdateStarted(std::vector<SBListChunkRanges>* lists) OVERRIDE {
133 ADD_FAILURE() << "Not implemented.";
136 virtual void InsertChunks(const std::string& list_name,
137 const SBChunkList& chunks) OVERRIDE {
138 ADD_FAILURE() << "Not implemented.";
140 virtual void DeleteChunks(
141 const std::vector<SBChunkDelete>& chunk_deletes) OVERRIDE {
142 ADD_FAILURE() << "Not implemented.";
144 virtual void UpdateFinished(bool update_succeeded) OVERRIDE {
145 ADD_FAILURE() << "Not implemented.";
147 virtual void CacheHashResults(const std::vector<SBPrefix>& prefixes,
148 const std::vector<SBFullHashResult>& full_hits) OVERRIDE {
149 // Do nothing for the cache.
151 virtual bool IsMalwareIPMatchKillSwitchOn() OVERRIDE {
155 // Fill up the database with test URL.
156 void AddUrl(const GURL& url,
157 const std::string& list_name,
158 const std::vector<SBPrefix>& prefix_hits,
159 const std::vector<SBFullHashResult>& full_hits) {
160 badurls_[url.spec()].list_name = list_name;
161 badurls_[url.spec()].prefix_hits = prefix_hits;
162 badurls_[url.spec()].full_hits = full_hits;
165 // Fill up the database with test hash digest.
166 void AddDownloadPrefix(SBPrefix prefix) {
167 download_digest_prefix_.insert(prefix);
172 std::string list_name;
173 std::vector<SBPrefix> prefix_hits;
174 std::vector<SBFullHashResult> full_hits;
177 bool ContainsUrl(const std::string& list_name0,
178 const std::string& list_name1,
179 const std::vector<GURL>& urls,
180 std::vector<SBPrefix>* prefix_hits,
181 std::vector<SBFullHashResult>* full_hits) {
183 for (size_t i = 0; i < urls.size(); ++i) {
184 const GURL& url = urls[i];
185 base::hash_map<std::string, Hits>::const_iterator
186 badurls_it = badurls_.find(url.spec());
188 if (badurls_it == badurls_.end())
191 if (badurls_it->second.list_name == list_name0 ||
192 badurls_it->second.list_name == list_name1) {
193 prefix_hits->insert(prefix_hits->end(),
194 badurls_it->second.prefix_hits.begin(),
195 badurls_it->second.prefix_hits.end());
196 full_hits->insert(full_hits->end(),
197 badurls_it->second.full_hits.begin(),
198 badurls_it->second.full_hits.end());
206 base::hash_map<std::string, Hits> badurls_;
207 base::hash_set<SBPrefix> download_digest_prefix_;
210 // Factory that creates TestSafeBrowsingDatabase instances.
211 class TestSafeBrowsingDatabaseFactory : public SafeBrowsingDatabaseFactory {
213 TestSafeBrowsingDatabaseFactory() : db_(NULL) {}
214 virtual ~TestSafeBrowsingDatabaseFactory() {}
216 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase(
217 bool enable_download_protection,
218 bool enable_client_side_whitelist,
219 bool enable_download_whitelist,
220 bool enable_extension_blacklist,
221 bool enable_side_effect_free_whitelist,
222 bool enable_ip_blacklist) OVERRIDE {
223 db_ = new TestSafeBrowsingDatabase();
226 TestSafeBrowsingDatabase* GetDb() {
230 // Owned by the SafebrowsingService.
231 TestSafeBrowsingDatabase* db_;
234 // A TestProtocolManager that could return fixed responses from
235 // safebrowsing server for testing purpose.
236 class TestProtocolManager : public SafeBrowsingProtocolManager {
238 TestProtocolManager(SafeBrowsingProtocolManagerDelegate* delegate,
239 net::URLRequestContextGetter* request_context_getter,
240 const SafeBrowsingProtocolConfig& config)
241 : SafeBrowsingProtocolManager(delegate, request_context_getter, config) {
245 virtual ~TestProtocolManager() {
249 // This function is called when there is a prefix hit in local safebrowsing
250 // database and safebrowsing service issues a get hash request to backends.
251 // We return a result from the prefilled full_hashes_ hash_map to simulate
252 // server's response. At the same time, latency is added to simulate real
253 // life network issues.
254 virtual void GetFullHash(
255 const std::vector<SBPrefix>& prefixes,
256 SafeBrowsingProtocolManager::FullHashCallback callback,
257 bool is_download) OVERRIDE {
258 BrowserThread::PostDelayedTask(
259 BrowserThread::IO, FROM_HERE,
260 base::Bind(InvokeFullHashCallback, callback, full_hashes_),
264 // Prepare the GetFullHash results for the next request.
265 void SetGetFullHashResponse(const SBFullHashResult& full_hash_result) {
266 full_hashes_.clear();
267 full_hashes_.push_back(full_hash_result);
270 void IntroduceDelay(const base::TimeDelta& delay) {
274 static int create_count() {
275 return create_count_;
278 static int delete_count() {
279 return delete_count_;
283 std::vector<SBFullHashResult> full_hashes_;
284 base::TimeDelta delay_;
285 static int create_count_;
286 static int delete_count_;
290 int TestProtocolManager::create_count_ = 0;
292 int TestProtocolManager::delete_count_ = 0;
294 // Factory that creates TestProtocolManager instances.
295 class TestSBProtocolManagerFactory : public SBProtocolManagerFactory {
297 TestSBProtocolManagerFactory() : pm_(NULL) {}
298 virtual ~TestSBProtocolManagerFactory() {}
300 virtual SafeBrowsingProtocolManager* CreateProtocolManager(
301 SafeBrowsingProtocolManagerDelegate* delegate,
302 net::URLRequestContextGetter* request_context_getter,
303 const SafeBrowsingProtocolConfig& config) OVERRIDE {
304 pm_ = new TestProtocolManager(delegate, request_context_getter, config);
308 TestProtocolManager* GetProtocolManager() {
313 // Owned by the SafebrowsingService.
314 TestProtocolManager* pm_;
317 class MockObserver : public SafeBrowsingUIManager::Observer {
320 virtual ~MockObserver() {}
321 MOCK_METHOD1(OnSafeBrowsingHit,
322 void(const SafeBrowsingUIManager::UnsafeResource&));
325 MATCHER_P(IsUnsafeResourceFor, url, "") {
326 return (arg.url.spec() == url.spec() &&
327 arg.threat_type != SB_THREAT_TYPE_SAFE);
330 // Tests the safe browsing blocking page in a browser.
331 class SafeBrowsingServiceTest : public InProcessBrowserTest {
333 SafeBrowsingServiceTest() {
336 static void GenUrlFullhashResult(const GURL& url,
337 const std::string& list_name,
339 SBFullHashResult* full_hash) {
342 safe_browsing_util::CanonicalizeUrl(url, &host, &path, NULL);
343 crypto::SHA256HashString(host + path, &full_hash->hash,
345 full_hash->list_name = list_name;
346 full_hash->add_chunk_id = add_chunk_id;
349 static void GenDigestFullhashResult(const std::string& full_digest,
350 const std::string& list_name,
352 SBFullHashResult* full_hash) {
353 full_hash->hash = safe_browsing_util::StringToSBFullHash(full_digest);
354 full_hash->list_name = list_name;
355 full_hash->add_chunk_id = add_chunk_id;
358 virtual void SetUp() {
359 // InProcessBrowserTest::SetUp() instantiates SafebrowsingService and
360 // RegisterFactory has to be called before SafeBrowsingService is created.
361 SafeBrowsingDatabase::RegisterFactory(&db_factory_);
362 SafeBrowsingProtocolManager::RegisterFactory(&pm_factory_);
363 InProcessBrowserTest::SetUp();
366 virtual void TearDown() {
367 InProcessBrowserTest::TearDown();
369 // Unregister test factories after InProcessBrowserTest::TearDown
370 // (which destructs SafeBrowsingService).
371 SafeBrowsingDatabase::RegisterFactory(NULL);
372 SafeBrowsingProtocolManager::RegisterFactory(NULL);
375 virtual void SetUpCommandLine(CommandLine* command_line) {
376 // Makes sure the auto update is not triggered during the test.
377 // This test will fill up the database using testing prefixes
379 command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
382 virtual void SetUpInProcessBrowserTestFixture() {
383 ASSERT_TRUE(test_server()->Start());
386 // This will setup the "url" prefix in database and prepare protocol manager
387 // to response with |full_hash| for get full hash request.
388 void SetupResponseForUrl(const GURL& url, const SBFullHashResult& full_hash) {
389 std::vector<SBPrefix> prefix_hits;
390 prefix_hits.push_back(full_hash.hash.prefix);
392 // Make sure the full hits is empty unless we need to test the
393 // full hash is hit in database's local cache.
394 std::vector<SBFullHashResult> empty_full_hits;
395 TestSafeBrowsingDatabase* db = db_factory_.GetDb();
396 db->AddUrl(url, full_hash.list_name, prefix_hits, empty_full_hits);
398 TestProtocolManager* pm = pm_factory_.GetProtocolManager();
399 pm->SetGetFullHashResponse(full_hash);
402 // This will setup the binary digest prefix in database and prepare protocol
403 // manager to respond with the result hash.
404 void SetupResponseForDigest(const std::string& digest,
405 const SBFullHashResult& hash_result) {
406 TestSafeBrowsingDatabase* db = db_factory_.GetDb();
407 db->AddDownloadPrefix(
408 safe_browsing_util::StringToSBFullHash(digest).prefix);
410 TestProtocolManager* pm = pm_factory_.GetProtocolManager();
411 pm->SetGetFullHashResponse(hash_result);
414 bool ShowingInterstitialPage() {
415 WebContents* contents =
416 browser()->tab_strip_model()->GetActiveWebContents();
417 InterstitialPage* interstitial_page = contents->GetInterstitialPage();
418 return interstitial_page != NULL;
421 void IntroduceGetHashDelay(const base::TimeDelta& delay) {
422 pm_factory_.GetProtocolManager()->IntroduceDelay(delay);
425 base::TimeDelta GetCheckTimeout(SafeBrowsingService* sb_service) {
426 return sb_service->database_manager()->check_timeout_;
429 void SetCheckTimeout(SafeBrowsingService* sb_service,
430 const base::TimeDelta& delay) {
431 sb_service->database_manager()->check_timeout_ = delay;
434 void CreateCSDService() {
435 safe_browsing::ClientSideDetectionService* csd_service =
436 safe_browsing::ClientSideDetectionService::Create(NULL);
437 SafeBrowsingService* sb_service =
438 g_browser_process->safe_browsing_service();
439 sb_service->csd_service_.reset(csd_service);
440 sb_service->RefreshState();
444 StrictMock<MockObserver> observer_;
446 // Temporary profile dir for test cases that create a second profile. This is
447 // owned by the SafeBrowsingServiceTest object so that it will not get
448 // destructed until after the test Browser has been torn down, since the
449 // ImportantFileWriter may still be modifying it after the Profile object has
451 base::ScopedTempDir temp_profile_dir_;
453 // Waits for pending tasks on the IO thread to complete. This is useful
454 // to wait for the SafeBrowsingService to finish loading/stopping.
455 void WaitForIOThread() {
456 scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
457 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
458 ASSERT_TRUE(io_helper->Run());
462 TestSafeBrowsingDatabaseFactory db_factory_;
463 TestSBProtocolManagerFactory pm_factory_;
465 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceTest);
470 const char kEmptyPage[] = "files/empty.html";
471 const char kMalwareFile[] = "files/downloads/dangerous/dangerous.exe";
472 const char kMalwarePage[] = "files/safe_browsing/malware.html";
474 // This test goes through DownloadResourceHandler.
475 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Malware) {
476 GURL url = test_server()->GetURL(kEmptyPage);
477 g_browser_process->safe_browsing_service()->
478 ui_manager()->AddObserver(&observer_);
480 // After adding the url to safebrowsing database and getfullhash result,
481 // we should see the interstitial page.
482 SBFullHashResult malware_full_hash;
484 GenUrlFullhashResult(url, safe_browsing_util::kMalwareList, chunk_id,
486 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(url))).Times(1);
487 SetupResponseForUrl(url, malware_full_hash);
488 ui_test_utils::NavigateToURL(browser(), url);
489 EXPECT_TRUE(ShowingInterstitialPage());
490 g_browser_process->safe_browsing_service()->
491 ui_manager()->RemoveObserver(&observer_);
494 const char kPrefetchMalwarePage[] = "files/safe_browsing/prefetch_malware.html";
496 // This test confirms that prefetches don't themselves get the
497 // interstitial treatment.
498 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, Prefetch) {
499 GURL url = test_server()->GetURL(kPrefetchMalwarePage);
500 GURL malware_url = test_server()->GetURL(kMalwarePage);
501 g_browser_process->safe_browsing_service()->
502 ui_manager()->AddObserver(&observer_);
504 class SetPrefetchForTest {
506 explicit SetPrefetchForTest(bool prefetch)
507 : old_prefetch_state_(prerender::PrerenderManager::IsPrefetchEnabled()),
508 old_prerender_mode_(prerender::PrerenderManager::GetMode()) {
509 prerender::PrerenderManager::SetIsPrefetchEnabled(prefetch);
510 prerender::PrerenderManager::SetMode(
511 prerender::PrerenderManager::PRERENDER_MODE_DISABLED);
514 ~SetPrefetchForTest() {
515 prerender::PrerenderManager::SetIsPrefetchEnabled(old_prefetch_state_);
516 prerender::PrerenderManager::SetMode(old_prerender_mode_);
519 bool old_prefetch_state_;
520 prerender::PrerenderManager::PrerenderManagerMode old_prerender_mode_;
521 } set_prefetch_for_test(true);
523 // Even though we have added this uri to the safebrowsing database and
524 // getfullhash result, we should not see the interstitial page since the
525 // only malware was a prefetch target.
526 SBFullHashResult malware_full_hash;
528 GenUrlFullhashResult(malware_url, safe_browsing_util::kMalwareList,
529 chunk_id, &malware_full_hash);
530 SetupResponseForUrl(malware_url, malware_full_hash);
531 ui_test_utils::NavigateToURL(browser(), url);
532 EXPECT_FALSE(ShowingInterstitialPage());
533 Mock::VerifyAndClear(&observer_);
535 // However, when we navigate to the malware page, we should still get
537 EXPECT_CALL(observer_, OnSafeBrowsingHit(IsUnsafeResourceFor(malware_url)))
539 ui_test_utils::NavigateToURL(browser(), malware_url);
540 EXPECT_TRUE(ShowingInterstitialPage());
541 Mock::VerifyAndClear(&observer_);
542 g_browser_process->safe_browsing_service()->
543 ui_manager()->RemoveObserver(&observer_);
549 : public base::RefCountedThreadSafe<TestSBClient>,
550 public SafeBrowsingDatabaseManager::Client {
553 : threat_type_(SB_THREAT_TYPE_SAFE),
554 safe_browsing_service_(g_browser_process->safe_browsing_service()) {
557 SBThreatType GetThreatType() const {
561 void CheckDownloadUrl(const std::vector<GURL>& url_chain) {
562 BrowserThread::PostTask(
563 BrowserThread::IO, FROM_HERE,
564 base::Bind(&TestSBClient::CheckDownloadUrlOnIOThread,
566 content::RunMessageLoop(); // Will stop in OnCheckDownloadUrlResult.
569 void CheckDownloadHash(const std::string& full_hash) {
570 BrowserThread::PostTask(
571 BrowserThread::IO, FROM_HERE,
572 base::Bind(&TestSBClient::CheckDownloadHashOnIOThread,
574 content::RunMessageLoop(); // Will stop in OnCheckDownloadHashResult.
578 friend class base::RefCountedThreadSafe<TestSBClient>;
579 virtual ~TestSBClient() {}
581 void CheckDownloadUrlOnIOThread(const std::vector<GURL>& url_chain) {
582 safe_browsing_service_->database_manager()->
583 CheckDownloadUrl(url_chain, this);
586 void CheckDownloadHashOnIOThread(const std::string& full_hash) {
587 safe_browsing_service_->database_manager()->
588 CheckDownloadHash(full_hash, this);
591 // Called when the result of checking a download URL is known.
592 virtual void OnCheckDownloadUrlResult(const std::vector<GURL>& url_chain,
593 SBThreatType threat_type) OVERRIDE {
594 threat_type_ = threat_type;
595 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
596 base::Bind(&TestSBClient::DownloadCheckDone, this));
599 // Called when the result of checking a download hash is known.
600 virtual void OnCheckDownloadHashResult(const std::string& hash,
601 SBThreatType threat_type) OVERRIDE {
602 threat_type_ = threat_type;
603 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
604 base::Bind(&TestSBClient::DownloadCheckDone, this));
607 void DownloadCheckDone() {
608 base::MessageLoopForUI::current()->Quit();
611 SBThreatType threat_type_;
612 SafeBrowsingService* safe_browsing_service_;
614 DISALLOW_COPY_AND_ASSIGN(TestSBClient);
617 // These tests use SafeBrowsingService::Client to directly interact with
618 // SafeBrowsingService.
621 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrl) {
622 GURL badbin_url = test_server()->GetURL(kMalwareFile);
623 std::vector<GURL> badbin_urls(1, badbin_url);
625 scoped_refptr<TestSBClient> client(new TestSBClient);
626 client->CheckDownloadUrl(badbin_urls);
628 // Since badbin_url is not in database, it is considered to be safe.
629 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
631 SBFullHashResult full_hash_result;
633 GenUrlFullhashResult(badbin_url, safe_browsing_util::kBinUrlList,
634 chunk_id, &full_hash_result);
635 SetupResponseForUrl(badbin_url, full_hash_result);
637 client->CheckDownloadUrl(badbin_urls);
639 // Now, the badbin_url is not safe since it is added to download database.
640 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
643 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlRedirects) {
644 GURL original_url = test_server()->GetURL(kEmptyPage);
645 GURL badbin_url = test_server()->GetURL(kMalwareFile);
646 GURL final_url = test_server()->GetURL(kEmptyPage);
647 std::vector<GURL> badbin_urls;
648 badbin_urls.push_back(original_url);
649 badbin_urls.push_back(badbin_url);
650 badbin_urls.push_back(final_url);
652 scoped_refptr<TestSBClient> client(new TestSBClient);
653 client->CheckDownloadUrl(badbin_urls);
655 // Since badbin_url is not in database, it is considered to be safe.
656 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
658 SBFullHashResult full_hash_result;
660 GenUrlFullhashResult(badbin_url, safe_browsing_util::kBinUrlList,
661 chunk_id, &full_hash_result);
662 SetupResponseForUrl(badbin_url, full_hash_result);
664 client->CheckDownloadUrl(badbin_urls);
666 // Now, the badbin_url is not safe since it is added to download database.
667 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
670 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadHash) {
671 const std::string full_hash = "12345678902234567890323456789012";
673 scoped_refptr<TestSBClient> client(new TestSBClient);
674 client->CheckDownloadHash(full_hash);
676 // Since badbin_url is not in database, it is considered to be safe.
677 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
679 SBFullHashResult full_hash_result;
681 GenDigestFullhashResult(full_hash, safe_browsing_util::kBinHashList,
682 chunk_id, &full_hash_result);
683 SetupResponseForDigest(full_hash, full_hash_result);
685 client->CheckDownloadHash(full_hash);
687 // Now, the badbin_url is not safe since it is added to download database.
688 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_HASH, client->GetThreatType());
691 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadUrlTimedOut) {
692 GURL badbin_url = test_server()->GetURL(kMalwareFile);
693 std::vector<GURL> badbin_urls(1, badbin_url);
695 scoped_refptr<TestSBClient> client(new TestSBClient);
696 SBFullHashResult full_hash_result;
698 GenUrlFullhashResult(badbin_url, safe_browsing_util::kBinUrlList,
699 chunk_id, &full_hash_result);
700 SetupResponseForUrl(badbin_url, full_hash_result);
701 client->CheckDownloadUrl(badbin_urls);
703 // badbin_url is not safe since it is added to download database.
704 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_URL, client->GetThreatType());
707 // Now introducing delays and we should hit timeout.
709 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
710 base::TimeDelta default_urlcheck_timeout =
711 GetCheckTimeout(sb_service);
712 IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1));
713 SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1));
714 client->CheckDownloadUrl(badbin_urls);
716 // There should be a timeout and the hash would be considered as safe.
717 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
719 // Need to set the timeout back to the default value.
720 SetCheckTimeout(sb_service, default_urlcheck_timeout);
723 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, CheckDownloadHashTimedOut) {
724 const std::string full_hash = "12345678902234567890323456789012";
726 scoped_refptr<TestSBClient> client(new TestSBClient);
727 SBFullHashResult full_hash_result;
729 GenDigestFullhashResult(full_hash, safe_browsing_util::kBinHashList,
730 chunk_id, &full_hash_result);
731 SetupResponseForDigest(full_hash, full_hash_result);
732 client->CheckDownloadHash(full_hash);
734 // The badbin_url is not safe since it is added to download database.
735 EXPECT_EQ(SB_THREAT_TYPE_BINARY_MALWARE_HASH, client->GetThreatType());
738 // Now introducing delays and we should hit timeout.
740 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
741 base::TimeDelta default_hashcheck_timeout =
742 GetCheckTimeout(sb_service);
743 IntroduceGetHashDelay(base::TimeDelta::FromSeconds(1));
744 SetCheckTimeout(sb_service, base::TimeDelta::FromMilliseconds(1));
745 client->CheckDownloadHash(full_hash);
747 // There should be a timeout and the hash would be considered as safe.
748 EXPECT_EQ(SB_THREAT_TYPE_SAFE, client->GetThreatType());
750 // Need to set the timeout back to the default value.
751 SetCheckTimeout(sb_service, default_hashcheck_timeout);
754 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceTest, StartAndStop) {
756 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
757 safe_browsing::ClientSideDetectionService* csd_service =
758 sb_service->safe_browsing_detection_service();
759 PrefService* pref_service = browser()->profile()->GetPrefs();
761 ASSERT_TRUE(sb_service != NULL);
762 ASSERT_TRUE(csd_service != NULL);
763 ASSERT_TRUE(pref_service != NULL);
765 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
767 // SBS might still be starting, make sure this doesn't flake.
769 EXPECT_TRUE(sb_service->enabled());
770 EXPECT_TRUE(csd_service->enabled());
772 // Add a new Profile. SBS should keep running.
773 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
774 scoped_ptr<Profile> profile2(Profile::CreateProfile(
775 temp_profile_dir_.path(), NULL, Profile::CREATE_MODE_SYNCHRONOUS));
776 ASSERT_TRUE(profile2.get() != NULL);
777 StartupTaskRunnerServiceFactory::GetForProfile(profile2.get())->
778 StartDeferredTaskRunners();
779 PrefService* pref_service2 = profile2->GetPrefs();
780 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
781 // We don't expect the state to have changed, but if it did, wait for it.
783 EXPECT_TRUE(sb_service->enabled());
784 EXPECT_TRUE(csd_service->enabled());
786 // Change one of the prefs. SBS should keep running.
787 pref_service->SetBoolean(prefs::kSafeBrowsingEnabled, false);
789 EXPECT_TRUE(sb_service->enabled());
790 EXPECT_TRUE(csd_service->enabled());
792 // Change the other pref. SBS should stop now.
793 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, false);
795 EXPECT_FALSE(sb_service->enabled());
796 EXPECT_FALSE(csd_service->enabled());
798 // Turn it back on. SBS comes back.
799 pref_service2->SetBoolean(prefs::kSafeBrowsingEnabled, true);
801 EXPECT_TRUE(sb_service->enabled());
802 EXPECT_TRUE(csd_service->enabled());
804 // Delete the Profile. SBS stops again.
805 pref_service2 = NULL;
808 EXPECT_FALSE(sb_service->enabled());
809 EXPECT_FALSE(csd_service->enabled());
814 class SafeBrowsingServiceShutdownTest : public SafeBrowsingServiceTest {
816 virtual void TearDown() OVERRIDE {
817 // Browser should be fully torn down by now, so we can safely check these
819 EXPECT_EQ(1, TestProtocolManager::create_count());
820 EXPECT_EQ(1, TestProtocolManager::delete_count());
822 SafeBrowsingServiceTest::TearDown();
825 // An observer that returns back to test code after a new profile is
827 void OnUnblockOnProfileCreation(Profile* profile,
828 Profile::CreateStatus status) {
829 if (status == Profile::CREATE_STATUS_INITIALIZED) {
831 base::MessageLoop::current()->Quit();
839 IN_PROC_BROWSER_TEST_F(SafeBrowsingServiceShutdownTest,
840 DontStartAfterShutdown) {
842 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
843 safe_browsing::ClientSideDetectionService* csd_service =
844 sb_service->safe_browsing_detection_service();
845 PrefService* pref_service = browser()->profile()->GetPrefs();
847 ASSERT_TRUE(sb_service != NULL);
848 ASSERT_TRUE(csd_service != NULL);
849 ASSERT_TRUE(pref_service != NULL);
851 EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnabled));
853 // SBS might still be starting, make sure this doesn't flake.
855 EXPECT_EQ(1, TestProtocolManager::create_count());
856 EXPECT_EQ(0, TestProtocolManager::delete_count());
858 // Create an additional profile. We need to use the ProfileManager so that
859 // the profile will get destroyed in the normal browser shutdown process.
860 ProfileManager* profile_manager = g_browser_process->profile_manager();
861 ASSERT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
862 profile_manager->CreateProfileAsync(
863 temp_profile_dir_.path(),
864 base::Bind(&SafeBrowsingServiceShutdownTest::OnUnblockOnProfileCreation,
866 string16(), string16(), std::string());
868 // Spin to allow profile creation to take place, loop is terminated
869 // by OnUnblockOnProfileCreation when the profile is created.
870 content::RunMessageLoop();
872 PrefService* pref_service2 = profile2_->GetPrefs();
873 EXPECT_TRUE(pref_service2->GetBoolean(prefs::kSafeBrowsingEnabled));
875 // We don't expect the state to have changed, but if it did, wait for it.
877 EXPECT_EQ(1, TestProtocolManager::create_count());
878 EXPECT_EQ(0, TestProtocolManager::delete_count());
880 // End the test, shutting down the browser.
881 // SafeBrowsingServiceShutdownTest::TearDown will check the create_count and
882 // delete_count again.
885 class SafeBrowsingDatabaseManagerCookieTest : public InProcessBrowserTest {
887 SafeBrowsingDatabaseManagerCookieTest() {}
889 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
890 // We need to start the test server to get the host&port in the url.
891 ASSERT_TRUE(test_server()->Start());
893 // Makes sure the auto update is not triggered. This test will force the
894 // update when needed.
895 command_line->AppendSwitch(switches::kSbDisableAutoUpdate);
897 // Point to the testing server for all SafeBrowsing requests.
898 GURL url_prefix = test_server()->GetURL(
899 "expect-and-set-cookie?expect=a%3db"
900 "&set=c%3dd%3b%20Expires=Fri,%2001%20Jan%202038%2001:01:01%20GMT"
902 command_line->AppendSwitchASCII(switches::kSbURLPrefix, url_prefix.spec());
905 virtual bool SetUpUserDataDirectory() OVERRIDE {
906 base::FilePath cookie_path(
907 SafeBrowsingService::GetCookieFilePathForTesting());
908 EXPECT_FALSE(base::PathExists(cookie_path));
910 base::FilePath test_dir;
911 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_dir)) {
916 // Initialize the SafeBrowsing cookies with a pre-created cookie store. It
917 // contains a single cookie, for domain 127.0.0.1, with value a=b, and
919 base::FilePath initial_cookies = test_dir.AppendASCII("safe_browsing")
920 .AppendASCII("Safe Browsing Cookies");
921 if (!base::CopyFile(initial_cookies, cookie_path)) {
927 if (!db.Open(cookie_path)) {
931 // Ensure the host value in the cookie file matches the test server we will
933 sql::Statement smt(db.GetUniqueStatement(
934 "UPDATE cookies SET host_key = ?"));
935 if (!smt.is_valid()) {
939 if (!smt.BindString(0, test_server()->host_port_pair().host())) {
948 return InProcessBrowserTest::SetUpUserDataDirectory();
951 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
952 InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
955 base::FilePath cookie_path(
956 SafeBrowsingService::GetCookieFilePathForTesting());
957 ASSERT_TRUE(db.Open(cookie_path));
959 sql::Statement smt(db.GetUniqueStatement(
960 "SELECT name, value FROM cookies ORDER BY name"));
961 ASSERT_TRUE(smt.is_valid());
963 ASSERT_TRUE(smt.Step());
964 ASSERT_EQ("a", smt.ColumnString(0));
965 ASSERT_EQ("b", smt.ColumnString(1));
966 ASSERT_TRUE(smt.Step());
967 ASSERT_EQ("c", smt.ColumnString(0));
968 ASSERT_EQ("d", smt.ColumnString(1));
969 EXPECT_FALSE(smt.Step());
972 virtual void SetUpOnMainThread() OVERRIDE {
973 sb_service_ = g_browser_process->safe_browsing_service();
974 ASSERT_TRUE(sb_service_.get() != NULL);
977 virtual void CleanUpOnMainThread() OVERRIDE {
982 sb_service_->protocol_manager()->ForceScheduleNextUpdate(
983 base::TimeDelta::FromSeconds(0));
986 scoped_refptr<SafeBrowsingService> sb_service_;
989 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingDatabaseManagerCookieTest);
992 // Test that a Safe Browsing database update request both sends cookies and can
994 IN_PROC_BROWSER_TEST_F(SafeBrowsingDatabaseManagerCookieTest,
995 TestSBUpdateCookies) {
996 content::WindowedNotificationObserver observer(
997 chrome::NOTIFICATION_SAFE_BROWSING_UPDATE_COMPLETE,
998 content::Source<SafeBrowsingDatabaseManager>(
999 sb_service_->database_manager().get()));
1000 BrowserThread::PostTask(
1003 base::Bind(&SafeBrowsingDatabaseManagerCookieTest::ForceUpdate, this));