diff options
author | paulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-19 21:58:14 +0000 |
---|---|---|
committer | paulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-19 21:58:14 +0000 |
commit | dfdb0de71597b036b48fc4b292912bab83a02a94 (patch) | |
tree | f47c2d08e30b942c940e79acdff44029b32c0c27 /chrome | |
parent | 070578438aad02cd5857bab0bcb3b3661048a982 (diff) | |
download | chromium_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')
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. |