summaryrefslogtreecommitdiffstats
path: root/chrome/browser/safe_browsing
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/safe_browsing')
-rw-r--r--chrome/browser/safe_browsing/bloom_filter.h2
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page.cc4
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page.h2
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc261
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc2
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.cc27
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.h38
7 files changed, 327 insertions, 9 deletions
diff --git a/chrome/browser/safe_browsing/bloom_filter.h b/chrome/browser/safe_browsing/bloom_filter.h
index fd69c0d..60cb4fc 100644
--- a/chrome/browser/safe_browsing/bloom_filter.h
+++ b/chrome/browser/safe_browsing/bloom_filter.h
@@ -58,7 +58,7 @@ class BloomFilter : public base::RefCountedThreadSafe<BloomFilter> {
// Force a maximum size on the bloom filter to avoid using too much memory
// (in bytes).
- static const int kBloomFilterMaxSize = 2 * 1024 * 1024;
+ static const int kBloomFilterMaxSize = 3 * 1024 * 1024;
// Use the above constants to calculate an appropriate size to pass
// to the BloomFilter constructor based on the intended |key_count|.
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index d158b11..2601023 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -11,6 +11,7 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/i18n/rtl.h"
+#include "base/singleton.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
@@ -293,8 +294,7 @@ void SafeBrowsingBlockingPage::PopulatePhishingStringDictionary(
l10n_util::GetString(IDS_SAFE_BROWSING_PHISHING_HEADLINE),
l10n_util::GetStringF(IDS_SAFE_BROWSING_PHISHING_DESCRIPTION1,
UTF8ToWide(url().host())),
- l10n_util::GetStringF(IDS_SAFE_BROWSING_PHISHING_DESCRIPTION2,
- UTF8ToWide(url().host())),
+ l10n_util::GetString(IDS_SAFE_BROWSING_PHISHING_DESCRIPTION2),
L"");
strings->SetString("continue_button",
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
index 96d8bca..7e7cb22 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -68,6 +68,8 @@ class SafeBrowsingBlockingPage : public InterstitialPage {
typedef std::vector<SafeBrowsingService::UnsafeResource> UnsafeResourceList;
protected:
+ friend class SafeBrowsingBlockingPageTest;
+
// InterstitialPage method:
virtual void CommandReceived(const std::string& command);
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
new file mode 100644
index 0000000..fa30068
--- /dev/null
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -0,0 +1,261 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This test creates a fake safebrowsing service, where we can inject
+// malware and phishing urls. It then uses a real browser to go to
+// these urls, and sends "goback" or "proceed" commands and verifies
+// they work.
+
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
+#include "chrome/browser/safe_browsing/safe_browsing_service.h"
+#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+
+// A SafeBrowingService class that allows us to inject the malicious URLs.
+class FakeSafeBrowsingService : public SafeBrowsingService {
+ public:
+ FakeSafeBrowsingService() {}
+
+ virtual ~FakeSafeBrowsingService() {}
+
+ // Called on the IO thread to check if the given url is safe or not. If we
+ // can synchronously determine that the url is safe, CheckUrl returns true.
+ // Otherwise it returns false, and "client" is called asynchronously with the
+ // result when it is ready.
+ // Overrides SafeBrowsingService::CheckUrl.
+ virtual bool CheckUrl(const GURL& gurl, Client* client) {
+ const std::string& url = gurl.spec();
+ if (badurls[url] == URL_SAFE)
+ return true;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &FakeSafeBrowsingService::OnCheckDone,
+ url, client));
+ return false;
+ }
+
+ void OnCheckDone(std::string url, Client* client) {
+ client->OnUrlCheckResult(GURL(url), badurls[url]);
+ }
+
+ void AddURLResult(const GURL& url, UrlCheckResult checkresult) {
+ badurls[url.spec()] = checkresult;
+ }
+
+ private:
+ base::hash_map<std::string, UrlCheckResult> badurls;
+};
+
+// Factory that creates FakeSafeBrowsingService instances.
+class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
+ public:
+ TestSafeBrowsingServiceFactory() { }
+ virtual ~TestSafeBrowsingServiceFactory() { }
+
+ virtual SafeBrowsingService* CreateSafeBrowsingService() {
+ return new FakeSafeBrowsingService();
+ }
+};
+
+// Tests the safe browsing blocking page in a browser.
+class SafeBrowsingBlockingPageTest : public InProcessBrowserTest,
+ public SafeBrowsingService::Client {
+ public:
+ SafeBrowsingBlockingPageTest() {
+ }
+
+ virtual void SetUp() {
+ SafeBrowsingService::RegisterFactory(&factory);
+ InProcessBrowserTest::SetUp();
+ }
+
+ virtual void TearDown() {
+ InProcessBrowserTest::TearDown();
+ SafeBrowsingService::RegisterFactory(NULL);
+ }
+
+ virtual void SetUpInProcessBrowserTestFixture() {
+ ASSERT_TRUE(test_server()->Start());
+ }
+
+ // SafeBrowsingService::Client implementation.
+ virtual void OnUrlCheckResult(const GURL& url,
+ SafeBrowsingService::UrlCheckResult result) {
+ }
+ virtual void OnBlockingPageComplete(bool proceed) {
+ }
+
+ void AddURLResult(const GURL& url,
+ SafeBrowsingService::UrlCheckResult checkresult) {
+ FakeSafeBrowsingService* service =
+ static_cast<FakeSafeBrowsingService*>(
+ g_browser_process->resource_dispatcher_host()->
+ safe_browsing_service());
+
+ ASSERT_TRUE(service != NULL);
+ service->AddURLResult(url, checkresult);
+ }
+
+ void SendCommand(const std::string& command) {
+ TabContents* contents = browser()->GetSelectedTabContents();
+ SafeBrowsingBlockingPage* interstitial_page =
+ static_cast<SafeBrowsingBlockingPage*>(
+ contents->interstitial_page());
+ ASSERT_TRUE(interstitial_page);
+ interstitial_page->CommandReceived(command);
+ }
+
+ void DontProceedThroughInterstitial() {
+ TabContents* contents = browser()->GetSelectedTabContents();
+ InterstitialPage* interstitial_page = contents->interstitial_page();
+ ASSERT_TRUE(interstitial_page);
+ interstitial_page->DontProceed();
+ }
+
+ void ProceedThroughInterstitial() {
+ TabContents* contents = browser()->GetSelectedTabContents();
+ InterstitialPage* interstitial_page = contents->interstitial_page();
+ ASSERT_TRUE(interstitial_page);
+ interstitial_page->Proceed();
+ }
+
+ void AssertNoInterstitial() {
+ TabContents* contents = browser()->GetSelectedTabContents();
+ InterstitialPage* interstitial_page = contents->interstitial_page();
+ ASSERT_FALSE(interstitial_page);
+ }
+
+ void WaitForNavigation() {
+ NavigationController* controller =
+ &browser()->GetSelectedTabContents()->controller();
+ ui_test_utils::WaitForNavigation(controller);
+ }
+
+ private:
+ TestSafeBrowsingServiceFactory factory;
+
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageTest);
+};
+
+namespace {
+
+const char kEmptyPage[] = "files/empty.html";
+const char kMalwarePage[] = "files/safe_browsing/malware.html";
+const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html";
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareDontProceed) {
+ GURL url = test_server()->GetURL(kEmptyPage);
+ AddURLResult(url, SafeBrowsingService::URL_MALWARE);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"takeMeBack\""); // Simulate the user clicking "back"
+ AssertNoInterstitial(); // Assert the interstitial is gone
+ EXPECT_EQ(GURL(chrome::kAboutBlankURL), // Back to "about:blank"
+ browser()->GetSelectedTabContents()->GetURL());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareProceed) {
+ GURL url = test_server()->GetURL(kEmptyPage);
+ AddURLResult(url, SafeBrowsingService::URL_MALWARE);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"proceed\""); // Simulate the user clicking "proceed"
+ WaitForNavigation(); // Wait until we finish the navigation.
+ AssertNoInterstitial(); // Assert the interstitial is gone.
+ EXPECT_EQ(url, browser()->GetSelectedTabContents()->GetURL());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingDontProceed) {
+ GURL url = test_server()->GetURL(kEmptyPage);
+ AddURLResult(url, SafeBrowsingService::URL_PHISHING);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"takeMeBack\""); // Simulate the user clicking "proceed"
+ AssertNoInterstitial(); // Assert the interstitial is gone
+ EXPECT_EQ(GURL(chrome::kAboutBlankURL), // We are back to "about:blank".
+ browser()->GetSelectedTabContents()->GetURL());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingProceed) {
+ GURL url = test_server()->GetURL(kEmptyPage);
+ AddURLResult(url, SafeBrowsingService::URL_PHISHING);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"proceed\""); // Simulate the user clicking "proceed".
+ WaitForNavigation(); // Wait until we finish the navigation.
+ AssertNoInterstitial(); // Assert the interstitial is gone
+ EXPECT_EQ(url, browser()->GetSelectedTabContents()->GetURL());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingReportError) {
+ GURL url = test_server()->GetURL(kEmptyPage);
+ AddURLResult(url, SafeBrowsingService::URL_PHISHING);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"reportError\""); // Simulate the user clicking "report error"
+ WaitForNavigation(); // Wait until we finish the navigation.
+ AssertNoInterstitial(); // Assert the interstitial is gone
+
+ // We are in the error reporting page.
+ EXPECT_EQ("/safebrowsing/report_error/",
+ browser()->GetSelectedTabContents()->GetURL().path());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingLearnMore) {
+ GURL url = test_server()->GetURL(kEmptyPage);
+ AddURLResult(url, SafeBrowsingService::URL_PHISHING);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"learnMore\""); // Simulate the user clicking "learn more"
+ WaitForNavigation(); // Wait until we finish the navigation.
+ AssertNoInterstitial(); // Assert the interstitial is gone
+
+ // We are in the help page.
+ EXPECT_EQ("/support/bin/answer.py",
+ browser()->GetSelectedTabContents()->GetURL().path());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareIframeDontProceed) {
+ GURL url = test_server()->GetURL(kMalwarePage);
+ GURL iframe_url = test_server()->GetURL(kMalwareIframe);
+ AddURLResult(iframe_url, SafeBrowsingService::URL_MALWARE);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"takeMeBack\""); // Simulate the user clicking "back"
+ AssertNoInterstitial(); // Assert the interstitial is gone
+
+ EXPECT_EQ(GURL(chrome::kAboutBlankURL), // Back to "about:blank"
+ browser()->GetSelectedTabContents()->GetURL());
+}
+
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareIframeProceed) {
+ GURL url = test_server()->GetURL(kMalwarePage);
+ GURL iframe_url = test_server()->GetURL(kMalwareIframe);
+ AddURLResult(iframe_url, SafeBrowsingService::URL_MALWARE);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ SendCommand("\"proceed\""); // Simulate the user clicking "proceed"
+ AssertNoInterstitial(); // Assert the interstitial is gone
+
+ EXPECT_EQ(url, browser()->GetSelectedTabContents()->GetURL());
+}
+
+} // namespace
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
index f0670e4..60f1043 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -61,7 +61,7 @@ class SafeBrowsingBlockingPageTest : public RenderViewHostTestHarness,
: ui_thread_(BrowserThread::UI, MessageLoop::current()),
io_thread_(BrowserThread::IO, MessageLoop::current()) {
ResetUserResponse();
- service_ = new SafeBrowsingService();
+ service_ = SafeBrowsingService::CreateSafeBrowsingService();
}
virtual void SetUp() {
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index aac28cd..dbb28f1 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/path_service.h"
+#include "base/singleton.h"
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_thread.h"
@@ -49,6 +50,25 @@ static Profile* GetDefaultProfile() {
return profile_manager->GetDefaultProfile(user_data_dir);
}
+// static
+SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL;
+
+// The default SafeBrowsingServiceFactory. Global, made a singleton so we
+// don't leak it.
+class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory {
+ public:
+ virtual SafeBrowsingService* CreateSafeBrowsingService() {
+ return new SafeBrowsingService();
+ }
+
+ private:
+ friend struct DefaultSingletonTraits<SafeBrowsingServiceFactoryImpl>;
+
+ SafeBrowsingServiceFactoryImpl() { }
+
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactoryImpl);
+};
+
struct SafeBrowsingService::WhiteListedEntry {
int render_process_host_id;
int render_view_id;
@@ -74,6 +94,13 @@ SafeBrowsingService::SafeBrowsingCheck::SafeBrowsingCheck()
SafeBrowsingService::SafeBrowsingCheck::~SafeBrowsingCheck() {}
+/* static */
+SafeBrowsingService* SafeBrowsingService::CreateSafeBrowsingService() {
+ if (!factory_)
+ factory_ = Singleton<SafeBrowsingServiceFactoryImpl>::get();
+ return factory_->CreateSafeBrowsingService();
+}
+
SafeBrowsingService::SafeBrowsingService()
: database_(NULL),
protocol_manager_(NULL),
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index acecf4e..78e1cde 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -26,6 +26,7 @@
class PrefService;
class SafeBrowsingDatabase;
class SafeBrowsingProtocolManager;
+class SafeBrowsingServiceFactory;
class URLRequestContextGetter;
namespace base {
@@ -88,8 +89,14 @@ class SafeBrowsingService
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingCheck);
};
- // Creates the safe browsing service. Need to initialize before using.
- SafeBrowsingService();
+ // Makes the passed |factory| the factory used to instanciate
+ // a SafeBrowsingService. Useful for tests.
+ static void RegisterFactory(SafeBrowsingServiceFactory* factory) {
+ factory_ = factory;
+ }
+
+ // Create an instance of the safe browsing service.
+ static SafeBrowsingService* CreateSafeBrowsingService();
// Called on the UI thread to initialize the service.
void Initialize();
@@ -104,7 +111,7 @@ class SafeBrowsingService
// can synchronously determine that the url is safe, CheckUrl returns true.
// Otherwise it returns false, and "client" is called asynchronously with the
// result when it is ready.
- bool CheckUrl(const GURL& url, Client* client);
+ virtual bool CheckUrl(const GURL& url, Client* client);
// Called on the IO thread to cancel a pending check if the result is no
// longer needed.
@@ -174,7 +181,15 @@ class SafeBrowsingService
// the current page is 'safe'.
void LogPauseDelay(base::TimeDelta time);
+ protected:
+ // Creates the safe browsing service. Need to initialize before using.
+ SafeBrowsingService();
+
+ virtual ~SafeBrowsingService();
+
private:
+ friend class SafeBrowsingServiceFactoryImpl;
+
typedef std::set<SafeBrowsingCheck*> CurrentChecks;
typedef std::vector<SafeBrowsingCheck*> GetHashRequestors;
typedef base::hash_map<SBPrefix, GetHashRequestors> GetHashRequests;
@@ -192,8 +207,6 @@ class SafeBrowsingService
friend class base::RefCountedThreadSafe<SafeBrowsingService>;
friend class SafeBrowsingServiceTest;
- ~SafeBrowsingService();
-
// Called to initialize objects that are used on the io_thread.
void OnIOInitialize(const std::string& client_key,
const std::string& wrapped_key,
@@ -281,6 +294,11 @@ class SafeBrowsingService
bool is_subresource,
UrlCheckResult threat_type);
+ // The factory used to instanciate a SafeBrowsingService object.
+ // Useful for tests, so they can provide their own implementation of
+ // SafeBrowsingService.
+ static SafeBrowsingServiceFactory* factory_;
+
CurrentChecks checks_;
// Used for issuing only one GetHash request for a given prefix.
@@ -325,4 +343,14 @@ class SafeBrowsingService
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService);
};
+// Factory for creating SafeBrowsingService. Useful for tests.
+class SafeBrowsingServiceFactory {
+ public:
+ SafeBrowsingServiceFactory() { }
+ virtual ~SafeBrowsingServiceFactory() { }
+ virtual SafeBrowsingService* CreateSafeBrowsingService() = 0;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingServiceFactory);
+};
+
#endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_