summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-19 21:58:14 +0000
committerpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-19 21:58:14 +0000
commitdfdb0de71597b036b48fc4b292912bab83a02a94 (patch)
treef47c2d08e30b942c940e79acdff44029b32c0c27 /chrome
parent070578438aad02cd5857bab0bcb3b3661048a982 (diff)
downloadchromium_src-dfdb0de71597b036b48fc4b292912bab83a02a94.zip
chromium_src-dfdb0de71597b036b48fc4b292912bab83a02a94.tar.gz
chromium_src-dfdb0de71597b036b48fc4b292912bab83a02a94.tar.bz2
Report malware sub resources and their containing page to the
SafeBrowsing service for faster malware detection. Any malware resource that we detect on a page is reported if the page that contains it is not in the blacklist AND the user has opted in to reporting stats. BUG=7607 (http://crbug.com/7607) Review URL: http://codereview.chromium.org/21474 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/safe_browsing/protocol_manager.cc37
-rw-r--r--chrome/browser/safe_browsing/protocol_manager.h9
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.cc54
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.h6
4 files changed, 104 insertions, 2 deletions
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc
index df83f8e..eb556c0 100644
--- a/chrome/browser/safe_browsing/protocol_manager.cc
+++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -19,6 +19,7 @@
#include "chrome/common/env_vars.h"
#include "chrome/common/stl_util-inl.h"
#include "net/base/base64.h"
+#include "net/base/escape.h"
#include "net/base/load_flags.h"
using base::Time;
@@ -39,6 +40,10 @@ static const char* const kSbGetHashUrl =
static const char* const kSbNewKeyUrl =
"https://sb-ssl.google.com/safebrowsing/newkey?client=%s&appver=%s&pver=2.2";
+// URL for reporting malware pages.
+static const char* const kSbMalwareReportUrl =
+ "http://safebrowsing.clients.google.com/safebrowsing/report?evts=malblhit&evtd=%s&evtr=%s&evhr=%s&client=%s&appver=%s";
+
#if defined(GOOGLE_CHROME_BUILD)
static const char* const kSbClientName = "googlechrome";
#else
@@ -89,6 +94,10 @@ SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() {
STLDeleteContainerPairFirstPointers(hash_requests_.begin(),
hash_requests_.end());
hash_requests_.clear();
+
+ // Delete in-progress malware reports.
+ STLDeleteContainerPointers(malware_reports_.begin(), malware_reports_.end());
+ malware_reports_.clear();
}
// Public API used by the SafeBrowsingService ----------------------------------
@@ -165,6 +174,16 @@ void SafeBrowsingProtocolManager::OnURLFetchComplete(
bool parsed_ok = true;
bool must_back_off = false; // Reduce SafeBrowsing service query frequency.
+ // See if this is a malware report fetcher. We don't take any action for
+ // the response to those.
+ std::set<const URLFetcher*>::iterator mit = malware_reports_.find(source);
+ if (mit != malware_reports_.end()) {
+ const URLFetcher* report = *mit;
+ malware_reports_.erase(mit);
+ delete report;
+ return;
+ }
+
HashRequests::iterator it = hash_requests_.find(source);
if (it != hash_requests_.end()) {
// GetHash response.
@@ -555,6 +574,24 @@ void SafeBrowsingProtocolManager::OnChunkInserted() {
}
}
+void SafeBrowsingProtocolManager::ReportMalware(const GURL& malware_url,
+ const GURL& page_url,
+ const GURL& referrer_url) {
+ std::string report_str = StringPrintf(
+ kSbMalwareReportUrl,
+ EscapeQueryParamValue(malware_url.spec()).c_str(),
+ EscapeQueryParamValue(page_url.spec()).c_str(),
+ EscapeQueryParamValue(referrer_url.spec()).c_str(),
+ kSbClientName,
+ version_.c_str());
+ GURL report_url(report_str);
+ URLFetcher* report = new URLFetcher(report_url, URLFetcher::GET, this);
+ report->set_load_flags(net::LOAD_DISABLE_CACHE);
+ report->set_request_context(Profile::GetDefaultRequestContext());
+ report->Start();
+ malware_reports_.insert(report);
+}
+
// static
std::string SafeBrowsingProtocolManager::FormatList(
const SBListChunkRanges& list, bool use_mac) {
diff --git a/chrome/browser/safe_browsing/protocol_manager.h b/chrome/browser/safe_browsing/protocol_manager.h
index 6198ed4..3023a2c 100644
--- a/chrome/browser/safe_browsing/protocol_manager.h
+++ b/chrome/browser/safe_browsing/protocol_manager.h
@@ -11,6 +11,7 @@
// The SafeBrowsingProtocolParser class to do the actual parsing.
#include <deque>
+#include <set>
#include "base/hash_tables.h"
#include "base/scoped_ptr.h"
@@ -86,6 +87,11 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
// The last time we received an update.
base::Time last_update() const { return last_update_; }
+ // Report a malware resource to the SafeBrowsing service.
+ void ReportMalware(const GURL& malware_url,
+ const GURL& page_url,
+ const GURL& referrer_url);
+
private:
// Internal API for fetching information from the SafeBrowsing servers. The
// GetHash requests are higher priority since they can block user requests
@@ -223,6 +229,9 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
// Track the size of each update (in bytes).
int update_size_;
+ // Track outstanding malware report fetchers for clean up.
+ std::set<const URLFetcher*> malware_reports_;
+
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingProtocolManager);
};
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index b524f22..f79c238 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -17,7 +17,9 @@
#include "chrome/browser/safe_browsing/protocol_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
#include "chrome/browser/safe_browsing/safe_browsing_database.h"
+#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -284,8 +286,11 @@ void SafeBrowsingService::DisplayBlockingPage(const GURL& url,
void SafeBrowsingService::DoDisplayBlockingPage(
const UnsafeResource& resource) {
// The tab might have been closed.
- if (!tab_util::GetWebContentsByID(resource.render_process_host_id,
- resource.render_view_id)) {
+ WebContents* wc =
+ tab_util::GetWebContentsByID(resource.render_process_host_id,
+ resource.render_view_id);
+
+ if (!wc) {
// The tab is gone and we did not have a chance at showing the interstitial.
// Just act as "Don't Proceed" was chosen.
base::Thread* io_thread = g_browser_process->io_thread();
@@ -297,6 +302,30 @@ void SafeBrowsingService::DoDisplayBlockingPage(
this, &SafeBrowsingService::OnBlockingPageDone, resources, false));
return;
}
+
+ // Report the malware sub-resource to the SafeBrowsing servers if we have a
+ // malware sub-resource on a safe page and only if the user has opted in to
+ // reporting statistics.
+ PrefService* prefs = g_browser_process->local_state();
+ DCHECK(prefs);
+ if (prefs && prefs->GetBoolean(prefs::kMetricsReportingEnabled) &&
+ resource.resource_type != ResourceType::MAIN_FRAME &&
+ resource.threat_type == SafeBrowsingService::URL_MALWARE) {
+ GURL page_url = wc->GetURL();
+ GURL referrer_url;
+ if (wc->controller()) {
+ NavigationEntry* entry = wc->controller()->GetActiveEntry();
+ if (entry)
+ referrer_url = entry->referrer();
+ }
+ io_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &SafeBrowsingService::ReportMalware,
+ resource.url,
+ page_url,
+ referrer_url));
+ }
+
SafeBrowsingBlockingPage::ShowBlockingPage(this, resource);
}
@@ -728,3 +757,24 @@ void SafeBrowsingService::RunQueuedClients() {
}
}
+void SafeBrowsingService::ReportMalware(const GURL& malware_url,
+ const GURL& page_url,
+ const GURL& referrer_url) {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ // We need to access the database cache on the io_loop_ which is only allowed
+ // in the new SafeBrowsing database system.
+ if (!new_safe_browsing_ || !enabled_ || !database_)
+ return;
+
+ // Check if 'page_url' is already blacklisted (exists in our cache). Only
+ // report if it's not there.
+ std::string list;
+ std::vector<SBPrefix> prefix_hits;
+ std::vector<SBFullHashResult> full_hits;
+ database_->ContainsUrl(page_url, &list, &prefix_hits, &full_hits,
+ protocol_manager_->last_update());
+
+ if (full_hits.empty())
+ protocol_manager_->ReportMalware(malware_url, page_url, referrer_url);
+}
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index 0917ec9..89b1169 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -180,6 +180,12 @@ class SafeBrowsingService
bool new_safe_browsing() const { return new_safe_browsing_; }
+ // Report any pages that contain malware sub-resources to the SafeBrowsing
+ // service.
+ void ReportMalware(const GURL& malware_url,
+ const GURL& page_url,
+ const GURL& referrer_url);
+
private:
// Should only be called on db thread as SafeBrowsingDatabase is not
// threadsafe.