1// Copyright (c) 2011 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#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ 6#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ 7 8#include <string> 9#include <vector> 10 11#include "base/basictypes.h" 12#include "base/memory/ref_counted.h" 13#include "base/memory/scoped_ptr.h" 14#include "chrome/browser/safe_browsing/browser_feature_extractor.h" 15#include "chrome/browser/safe_browsing/database_manager.h" 16#include "chrome/browser/safe_browsing/ui_manager.h" 17#include "content/public/browser/notification_registrar.h" 18#include "content/public/browser/resource_request_details.h" 19#include "content/public/browser/web_contents_observer.h" 20#include "url/gurl.h" 21 22namespace safe_browsing { 23class ClientPhishingRequest; 24class ClientSideDetectionService; 25 26// This class is used to receive the IPC from the renderer which 27// notifies the browser that a URL was classified as phishing. This 28// class relays this information to the client-side detection service 29// class which sends a ping to a server to validate the verdict. 30// TODO(noelutz): move all client-side detection IPCs to this class. 31class ClientSideDetectionHost : public content::WebContentsObserver, 32 public content::NotificationObserver, 33 public SafeBrowsingUIManager::Observer { 34 public: 35 // The caller keeps ownership of the tab object and is responsible for 36 // ensuring that it stays valid until WebContentsDestroyed is called. 37 static ClientSideDetectionHost* Create(content::WebContents* tab); 38 virtual ~ClientSideDetectionHost(); 39 40 // From content::WebContentsObserver. 41 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 42 43 // From content::WebContentsObserver. If we navigate away we cancel all 44 // pending callbacks that could show an interstitial, and check to see whether 45 // we should classify the new URL. 46 virtual void DidNavigateMainFrame( 47 const content::LoadCommittedDetails& details, 48 const content::FrameNavigateParams& params) OVERRIDE; 49 50 // Called when the SafeBrowsingService found a hit with one of the 51 // SafeBrowsing lists. This method is called on the UI thread. 52 virtual void OnSafeBrowsingHit( 53 const SafeBrowsingUIManager::UnsafeResource& resource) OVERRIDE; 54 55 // Called when the SafeBrowsingService finds a match on the SB lists. 56 // Called on the UI thread. Called even if the resource is whitelisted. 57 virtual void OnSafeBrowsingMatch( 58 const SafeBrowsingUIManager::UnsafeResource& resource) OVERRIDE; 59 60 virtual scoped_refptr<SafeBrowsingDatabaseManager> database_manager(); 61 62 // Returns whether the current page contains a malware or phishing safe 63 // browsing match. 64 bool DidPageReceiveSafeBrowsingMatch() const; 65 66 protected: 67 explicit ClientSideDetectionHost(content::WebContents* tab); 68 69 // From content::WebContentsObserver. 70 virtual void WebContentsDestroyed() OVERRIDE; 71 72 // Used for testing. 73 void set_safe_browsing_managers( 74 SafeBrowsingUIManager* ui_manager, 75 SafeBrowsingDatabaseManager* database_manager); 76 77 private: 78 friend class ClientSideDetectionHostTest; 79 class ShouldClassifyUrlRequest; 80 friend class ShouldClassifyUrlRequest; 81 82 // These methods are called when pre-classification checks are done for 83 // the phishing and malware clasifiers. 84 void OnPhishingPreClassificationDone(bool should_classify); 85 void OnMalwarePreClassificationDone(bool should_classify); 86 87 // Verdict is an encoded ClientPhishingRequest protocol message. 88 void OnPhishingDetectionDone(const std::string& verdict); 89 90 // Callback that is called when the server ping back is 91 // done. Display an interstitial if |is_phishing| is true. 92 // Otherwise, we do nothing. Called in UI thread. 93 void MaybeShowPhishingWarning(GURL phishing_url, bool is_phishing); 94 95 // Callback that is called when the malware IP server ping back is 96 // done. Display an interstitial if |is_malware| is true. 97 // Otherwise, we do nothing. Called in UI thread. 98 void MaybeShowMalwareWarning(GURL original_url, GURL malware_url, 99 bool is_malware); 100 101 // Callback that is called when the browser feature extractor is done. 102 // This method is responsible for deleting the request object. Called on 103 // the UI thread. 104 void FeatureExtractionDone(bool success, 105 scoped_ptr<ClientPhishingRequest> request); 106 107 // Start malware classification once the onload handler was called and 108 // malware pre-classification checks are done and passed. 109 void MaybeStartMalwareFeatureExtraction(); 110 111 // Function to be called when the browser malware feature extractor is done. 112 // Called on the UI thread. 113 void MalwareFeatureExtractionDone( 114 bool success, scoped_ptr<ClientMalwareRequest> request); 115 116 // Update the entries in browse_info_->ips map. 117 void UpdateIPUrlMap(const std::string& ip, 118 const std::string& url, 119 const std::string& method, 120 const std::string& referrer, 121 const content::ResourceType resource_type); 122 123 // From NotificationObserver. Called when a notification comes in. This 124 // method is called in the UI thread. 125 virtual void Observe(int type, 126 const content::NotificationSource& source, 127 const content::NotificationDetails& details) OVERRIDE; 128 129 // Inherited from WebContentsObserver. This is called once the page is 130 // done loading. 131 virtual void DidStopLoading(content::RenderViewHost* rvh) OVERRIDE; 132 133 // Returns true if the user has seen a regular SafeBrowsing 134 // interstitial for the current page. This is only true if the user has 135 // actually clicked through the warning. This method is called on the UI 136 // thread. 137 bool DidShowSBInterstitial() const; 138 139 // Used for testing. This function does not take ownership of the service 140 // class. 141 void set_client_side_detection_service(ClientSideDetectionService* service); 142 143 // This pointer may be NULL if client-side phishing detection is disabled. 144 ClientSideDetectionService* csd_service_; 145 // These pointers may be NULL if SafeBrowsing is disabled. 146 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; 147 scoped_refptr<SafeBrowsingUIManager> ui_manager_; 148 // Keep a handle to the latest classification request so that we can cancel 149 // it if necessary. 150 scoped_refptr<ShouldClassifyUrlRequest> classification_request_; 151 // Browser-side feature extractor. 152 scoped_ptr<BrowserFeatureExtractor> feature_extractor_; 153 // Keeps some info about the current page visit while the renderer 154 // classification is going on. Since we cancel classification on 155 // every page load we can simply keep this data around as a member 156 // variable. This information will be passed on to the feature extractor. 157 scoped_ptr<BrowseInfo> browse_info_; 158 // Redirect chain that leads to the first page of the current host. We keep 159 // track of this for browse_info_. 160 std::vector<GURL> cur_host_redirects_; 161 // Current host, used to help determine cur_host_redirects_. 162 std::string cur_host_; 163 // Handles registering notifications with the NotificationService. 164 content::NotificationRegistrar registrar_; 165 166 // Max number of ips we save for each browse 167 static const size_t kMaxIPsPerBrowse; 168 // Max number of urls we report for each malware IP. 169 static const size_t kMaxUrlsPerIP; 170 171 bool should_extract_malware_features_; 172 bool should_classify_for_malware_; 173 bool pageload_complete_; 174 175 // Unique page ID of the most recent unsafe site that was loaded in this tab 176 // as well as the UnsafeResource. 177 int unsafe_unique_page_id_; 178 scoped_ptr<SafeBrowsingUIManager::UnsafeResource> unsafe_resource_; 179 180 base::WeakPtrFactory<ClientSideDetectionHost> weak_factory_; 181 182 DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionHost); 183}; 184 185} // namespace safe_browsing 186 187#endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ 188