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 <stddef.h> 9 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "chrome/browser/safe_browsing/client_side_model_loader.h" 17 #include "chrome/browser/safe_browsing/ui_manager.h" 18 #include "components/safe_browsing/content/common/safe_browsing.mojom-shared.h" 19 #include "components/safe_browsing/core/db/database_manager.h" 20 #include "content/public/browser/render_process_host.h" 21 #include "content/public/browser/web_contents_observer.h" 22 #include "mojo/public/cpp/bindings/remote.h" 23 #include "services/service_manager/public/cpp/binder_registry.h" 24 #include "url/gurl.h" 25 26 namespace base { 27 class TickClock; 28 } 29 30 namespace safe_browsing { 31 class ClientPhishingRequest; 32 class ClientSideDetectionService; 33 34 // This class is used to receive the IPC from the renderer which 35 // notifies the browser that a URL was classified as phishing. This 36 // class relays this information to the client-side detection service 37 // class which sends a ping to a server to validate the verdict. 38 // TODO(noelutz): move all client-side detection IPCs to this class. 39 class ClientSideDetectionHost : public content::WebContentsObserver { 40 public: 41 // The caller keeps ownership of the tab object and is responsible for 42 // ensuring that it stays valid until WebContentsDestroyed is called. 43 static std::unique_ptr<ClientSideDetectionHost> Create( 44 content::WebContents* tab); 45 ~ClientSideDetectionHost() override; 46 47 // From content::WebContentsObserver. If we navigate away we cancel all 48 // pending callbacks that could show an interstitial, and check to see whether 49 // we should classify the new URL. 50 void DidFinishNavigation( 51 content::NavigationHandle* navigation_handle) override; 52 53 // Send the model to all the render frame hosts in this WebContents. 54 void SendModelToRenderFrame(); 55 56 protected: 57 explicit ClientSideDetectionHost(content::WebContents* tab); 58 59 // From content::WebContentsObserver. 60 void WebContentsDestroyed() override; 61 void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; 62 63 // Used for testing. 64 void set_ui_manager(SafeBrowsingUIManager* ui_manager); 65 void set_database_manager(SafeBrowsingDatabaseManager* database_manager); 66 67 private: 68 friend class ClientSideDetectionHostTestBase; 69 class ShouldClassifyUrlRequest; 70 friend class ShouldClassifyUrlRequest; 71 FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostBrowserTest, 72 VerifyVisualFeatureCollection); 73 74 // Called when pre-classification checks are done for the phishing 75 // classifiers. 76 void OnPhishingPreClassificationDone(bool should_classify); 77 78 // |verdict| is an encoded ClientPhishingRequest protocol message, |result| is 79 // the outcome of the renderer classification. 80 void PhishingDetectionDone(mojom::PhishingDetectorResult result, 81 const std::string& verdict); 82 83 // Callback that is called when the server ping back is 84 // done. Display an interstitial if |is_phishing| is true. 85 // Otherwise, we do nothing. Called in UI thread. |is_from_cache| indicates 86 // whether the warning is being shown due to a cached verdict or from an 87 // actual server ping. 88 void MaybeShowPhishingWarning(bool is_from_cache, 89 GURL phishing_url, 90 bool is_phishing); 91 92 // Returns true if the user has seen a regular SafeBrowsing 93 // interstitial for the current page. This is only true if the user has 94 // actually clicked through the warning. This method is called on the UI 95 // thread. 96 bool DidShowSBInterstitial() const; 97 98 // Used for testing. This function does not take ownership of the service 99 // class. 100 void set_client_side_detection_service(ClientSideDetectionService* service); 101 102 // Sets a test tick clock only for testing. set_tick_clock_for_testing(const base::TickClock * tick_clock)103 void set_tick_clock_for_testing(const base::TickClock* tick_clock) { 104 tick_clock_ = tick_clock; 105 } 106 107 // This pointer may be nullptr if client-side phishing detection is disabled. 108 ClientSideDetectionService* csd_service_; 109 // The WebContents that the class is observing. 110 content::WebContents* tab_; 111 // These pointers may be nullptr if SafeBrowsing is disabled. 112 scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; 113 scoped_refptr<SafeBrowsingUIManager> ui_manager_; 114 // Keep a handle to the latest classification request so that we can cancel 115 // it if necessary. 116 scoped_refptr<ShouldClassifyUrlRequest> classification_request_; 117 // The current URL 118 GURL current_url_; 119 // Current host, used to help determine cur_host_redirects_. 120 std::string cur_host_; 121 // The currently active message pipe to the renderer PhishingDetector. 122 mojo::Remote<mojom::PhishingDetector> phishing_detector_; 123 124 // Max number of ips we save for each browse 125 static const size_t kMaxIPsPerBrowse; 126 bool pageload_complete_; 127 128 // Records the start time of when phishing detection started. 129 base::TimeTicks phishing_detection_start_time_; 130 const base::TickClock* tick_clock_; 131 base::WeakPtrFactory<ClientSideDetectionHost> weak_factory_{this}; 132 133 DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionHost); 134 }; 135 136 } // namespace safe_browsing 137 138 #endif // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_HOST_H_ 139