1 // Copyright (c) 2012 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 // Classes for managing the SafeBrowsing interstitial pages. 6 // 7 // When a user is about to visit a page the SafeBrowsing system has deemed to 8 // be malicious, either as malware or a phishing page, we show an interstitial 9 // page with some options (go back, continue) to give the user a chance to avoid 10 // the harmful page. 11 // 12 // The SafeBrowsingBlockingPage is created by the SafeBrowsingUIManager on the 13 // UI thread when we've determined that a page is malicious. The operation of 14 // the blocking page occurs on the UI thread, where it waits for the user to 15 // make a decision about what to do: either go back or continue on. 16 // 17 // The blocking page forwards the result of the user's choice back to the 18 // SafeBrowsingUIManager so that we can cancel the request for the new page, 19 // or allow it to continue. 20 // 21 // A web page may contain several resources flagged as malware/phishing. This 22 // results into more than one interstitial being shown. On the first unsafe 23 // resource received we show an interstitial. Any subsequent unsafe resource 24 // notifications while the first interstitial is showing is queued. If the user 25 // decides to proceed in the first interstitial, we display all queued unsafe 26 // resources in a new interstitial. 27 28 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_ 29 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_ 30 31 #include <map> 32 #include <string> 33 #include <vector> 34 35 #include "base/gtest_prod_util.h" 36 #include "base/task/cancelable_task_tracker.h" 37 #include "base/time/time.h" 38 #include "chrome/browser/history/history_service.h" 39 #include "chrome/browser/safe_browsing/ui_manager.h" 40 #include "content/public/browser/interstitial_page_delegate.h" 41 #include "url/gurl.h" 42 43 class MalwareDetails; 44 class SafeBrowsingBlockingPageFactory; 45 46 namespace base { 47 class DictionaryValue; 48 class MessageLoop; 49 } 50 51 namespace content { 52 class InterstitialPage; 53 class WebContents; 54 } 55 56 #if defined(ENABLE_EXTENSIONS) 57 namespace extensions { 58 class ExperienceSamplingEvent; 59 } 60 #endif 61 62 class SafeBrowsingBlockingPage : public content::InterstitialPageDelegate { 63 public: 64 typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource; 65 typedef std::vector<UnsafeResource> UnsafeResourceList; 66 typedef std::map<content::WebContents*, UnsafeResourceList> UnsafeResourceMap; 67 68 virtual ~SafeBrowsingBlockingPage(); 69 70 // Creates a blocking page. Use ShowBlockingPage if you don't need to access 71 // the blocking page directly. 72 static SafeBrowsingBlockingPage* CreateBlockingPage( 73 SafeBrowsingUIManager* ui_manager, 74 content::WebContents* web_contents, 75 const UnsafeResource& unsafe_resource); 76 77 // Shows a blocking page warning the user about phishing/malware for a 78 // specific resource. 79 // You can call this method several times, if an interstitial is already 80 // showing, the new one will be queued and displayed if the user decides 81 // to proceed on the currently showing interstitial. 82 static void ShowBlockingPage( 83 SafeBrowsingUIManager* ui_manager, const UnsafeResource& resource); 84 85 // Makes the passed |factory| the factory used to instantiate 86 // SafeBrowsingBlockingPage objects. Useful for tests. RegisterFactory(SafeBrowsingBlockingPageFactory * factory)87 static void RegisterFactory(SafeBrowsingBlockingPageFactory* factory) { 88 factory_ = factory; 89 } 90 91 // InterstitialPageDelegate method: 92 virtual std::string GetHTMLContents() OVERRIDE; 93 virtual void OnProceed() OVERRIDE; 94 virtual void OnDontProceed() OVERRIDE; 95 virtual void CommandReceived(const std::string& command) OVERRIDE; 96 virtual void OverrideRendererPrefs( 97 content::RendererPreferences* prefs) OVERRIDE; 98 99 protected: 100 friend class SafeBrowsingBlockingPageTest; 101 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest, 102 ProceedThenDontProceed); 103 104 void DontCreateViewForTesting(); 105 void Show(); 106 void SetReportingPreference(bool report); 107 void UpdateReportingPref(); // Used for the transition from old to new pref. 108 109 // Don't instantiate this class directly, use ShowBlockingPage instead. 110 SafeBrowsingBlockingPage(SafeBrowsingUIManager* ui_manager, 111 content::WebContents* web_contents, 112 const UnsafeResourceList& unsafe_resources); 113 114 // After a malware interstitial where the user opted-in to the 115 // report but clicked "proceed anyway", we delay the call to 116 // MalwareDetails::FinishCollection() by this much time (in 117 // milliseconds), in order to get data from the blocked resource itself. 118 int64 malware_details_proceed_delay_ms_; interstitial_page()119 content::InterstitialPage* interstitial_page() const { 120 return interstitial_page_; 121 } 122 123 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest, 124 MalwareReportsTransitionDisabled); 125 FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest, 126 MalwareReportsToggling); 127 128 // These enums are used for histograms. Don't reorder, delete, or insert 129 // elements. New elements should be added before MAX_ACTION only. 130 enum Decision { 131 SHOW, 132 PROCEED, 133 DONT_PROCEED, 134 PROCEEDING_DISABLED, 135 MAX_DECISION 136 }; 137 enum Interaction { 138 TOTAL_VISITS, 139 SHOW_ADVANCED, 140 SHOW_PRIVACY_POLICY, 141 SHOW_DIAGNOSTIC, 142 SHOW_LEARN_MORE, 143 MAX_INTERACTION 144 }; 145 146 // Record a user decision or interaction to the appropriate UMA histogram. 147 void RecordUserDecision(Decision decision); 148 void RecordUserInteraction(Interaction interaction); 149 150 // Used to query the HistoryService to see if the URL is in history. For UMA. 151 void OnGotHistoryCount(bool success, int num_visits, base::Time first_visit); 152 153 // Checks if we should even show the malware details option. For example, we 154 // don't show it in incognito mode. 155 bool CanShowMalwareDetailsOption(); 156 157 // Called when the insterstitial is going away. If there is a 158 // pending malware details object, we look at the user's 159 // preferences, and if the option to send malware details is 160 // enabled, the report is scheduled to be sent on the |ui_manager_|. 161 void FinishMalwareDetails(int64 delay_ms); 162 163 // Returns the boolean value of the given |pref| from the PrefService of the 164 // Profile associated with |web_contents_|. 165 bool IsPrefEnabled(const char* pref); 166 167 // A list of SafeBrowsingUIManager::UnsafeResource for a tab that the user 168 // should be warned about. They are queued when displaying more than one 169 // interstitial at a time. 170 static UnsafeResourceMap* GetUnsafeResourcesMap(); 171 172 // Notifies the SafeBrowsingUIManager on the IO thread whether to proceed 173 // or not for the |resources|. 174 static void NotifySafeBrowsingUIManager( 175 SafeBrowsingUIManager* ui_manager, 176 const UnsafeResourceList& resources, bool proceed); 177 178 // Returns true if the passed |unsafe_resources| is blocking the load of 179 // the main page. 180 static bool IsMainPageLoadBlocked( 181 const UnsafeResourceList& unsafe_resources); 182 183 friend class SafeBrowsingBlockingPageFactoryImpl; 184 185 // For reporting back user actions. 186 SafeBrowsingUIManager* ui_manager_; 187 base::MessageLoop* report_loop_; 188 189 // True if the interstitial is blocking the main page because it is on one 190 // of our lists. False if a subresource is being blocked, or in the case of 191 // client-side detection where the interstitial is shown after page load 192 // finishes. 193 bool is_main_frame_load_blocked_; 194 195 // The index of a navigation entry that should be removed when DontProceed() 196 // is invoked, -1 if not entry should be removed. 197 int navigation_entry_index_to_remove_; 198 199 // The list of unsafe resources this page is warning about. 200 UnsafeResourceList unsafe_resources_; 201 202 // A MalwareDetails object that we start generating when the 203 // blocking page is shown. The object will be sent when the warning 204 // is gone (if the user enables the feature). 205 scoped_refptr<MalwareDetails> malware_details_; 206 207 bool proceeded_; 208 209 content::WebContents* web_contents_; 210 GURL url_; 211 content::InterstitialPage* interstitial_page_; // Owns us 212 213 // Whether the interstitial should create a view. 214 bool create_view_; 215 216 // Which type of interstitial this is. 217 enum { 218 TYPE_MALWARE, 219 TYPE_HARMFUL, 220 TYPE_PHISHING, 221 } interstitial_type_; 222 223 // The factory used to instantiate SafeBrowsingBlockingPage objects. 224 // Usefull for tests, so they can provide their own implementation of 225 // SafeBrowsingBlockingPage. 226 static SafeBrowsingBlockingPageFactory* factory_; 227 228 // How many times is this same URL in history? Used for histogramming. 229 int num_visits_; 230 base::CancelableTaskTracker request_tracker_; 231 232 private: 233 // Fills the passed dictionary with the values to be passed to the template 234 // when creating the HTML. 235 void PopulateMalwareLoadTimeData(base::DictionaryValue* load_time_data); 236 void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data); 237 void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data); 238 239 #if defined(ENABLE_EXTENSIONS) 240 scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_; 241 #endif 242 243 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPage); 244 }; 245 246 // Factory for creating SafeBrowsingBlockingPage. Useful for tests. 247 class SafeBrowsingBlockingPageFactory { 248 public: ~SafeBrowsingBlockingPageFactory()249 virtual ~SafeBrowsingBlockingPageFactory() { } 250 251 virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage( 252 SafeBrowsingUIManager* ui_manager, 253 content::WebContents* web_contents, 254 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) = 0; 255 }; 256 257 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_BLOCKING_PAGE_H_ 258